众所周知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-100
、red-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"