你不知道的Typescript-模板字面量

24年 8月 21日 星期三
402字
3分钟

众所周知Typescript中有string类型,来表明一个值是字符串,但是它太宽泛了,考虑以下情况:

现在需要一个文件名的类型,大家肯定能想到string,但是会带来一个问题:如何保证文件的后缀呢?你可能想到这样做:

typescript
type FileName = string;

let fileName: FileName = "somefile.ext";

//现在需要判断文件后缀是不是`.png`
let isPng = fileName.endsWith(".png");

如果这样做的话,FileName类型似乎没有存在的意义了...

模板字面量

其实我们可以使用JavaScript中模板字符串的方法来定义类型:

typescript
type PNG = `${string}.png`

let somePNG: PNG = "image.png"; //✅ correct

let someJPG: PNG = "image.jpg";  //❌ error: 不能将类型“"image.jpg"”分配给类型“`${string}.png`”。

模板字面量给string类型带来了很大的灵活性

你也可以用来约束字符串以什么开头

typescript
type APIPath = `/api/${string}`;

let userInfoPath: APIPath = "/api/userinfo"; //✅ correct
let aboutPath: APIPath = "/about"; //❌ error: 不能将类型“"/about"”分配给类型“`/api/${string}`”。

将模板文字类型与联合类型组合

想象一下你现在是一位组件库开发者,你需要设计你的色彩系统,类似于:red-100red-200...,你如何设计它的的类型呢?纯手写吗?

大可不必!

现在可以将模板文字类型与联合类型组合:

typescript
type Opacity = 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
type Color = "red" | "green" | "blue";

type ColorWithOpacity = `${Color}-${Opacity}`;
// type ColorWithOpacity = "red-100" | "red-200" | "red-300" | "red-400" | "red-500" | "red-600" | "red-700" | "red-800" | "red-900" | "green-100" | "green-200" | "green-300" | "green-400" | "green-500" | ... 12 more ... | "blue-900"