TypeScript 中的模板字面量类型是一种强大的类型定义方式, 允许你通过模板字符串的语法来构造新的字符串字面量类型。这个特性在 TypeScript 4.1 版本中引入。以下是关于模板字面量类型的详细解释和示例:
- 基本语法
模板字面量类型使用反引号 (`)来定义,类似于JavaScript的模板字符串:
type Greeting = `Hello, ${string}`;- 使用联合类型
你可以在模板字面量中使用联合类型:
type Color = 'red' | 'blue' | 'green';
type Size = 'small' | 'medium' | 'large';
type ColorSize = `${Color}-${Size}`;
// 'red-small' | 'red-medium' | 'red-large' | 'blue-small' | ...- 与泛型结合使用
模板字面量类型可以与泛型结合使用:
type PropEventSource<Type> = {
on(eventName: `${string & keyof Type}Changed`, callback: (newValue: any) => void): void;
};
interface Person {
name: string;
age: number;
}
const person: PropEventSource<Person> = {
on(eventName: 'nameChanged' | 'ageChanged', callback: (newValue: any) => void) {
// 实现省略
}
};
person.on('nameChanged', (newName) => {});
person.on('ageChanged', (newAge) => {});
// person.on('locationChanged', () => {}); // 错误: 'locationChanged' 不是有效的事件名- 内置字符串操作类型
TypeScript 提供了几个内置的字符串操作类型, 可以与模板字面量类型一起使用:
Uppercase<StringType>Lowercase<StringType>Capitalize<StringType>Uncapitalize<StringType>
例如:
type Greeting = "Hello, world";
type ShoutyGreeting = Uppercase<Greeting>; // "HELLO, WORLD"
type QuietGreeting = Lowercase<Greeting>; // "hello, world"
type HelloGreeting = Capitalize<"hello, world">; // "Hello, world"
type HelloGreeting = Uncapitalize<"Hello, world">; // "hello, world"- 实际应用示例
模板字面量类型在创建复杂的字符串操作类型时特别有用:
// 创建一个类型安全的 CSS-in-JS 库
type CSSProperty = 'color' | 'background-color' | 'margin';
type CSSValue = string;
type CSSRule = `${CSSProperty}: ${CSSValue}`;
function applyCSS(rule: CSSRule) {
// 实现省略
}
applyCSS('color: red'); // 正确
applyCSS('margin: 10px'); // 正确
// applyCSS('font: bold'); // 错误: 'font' 不是有效的 CSSProperty- 条件类型中的推断
在条件类型中, 你可以使用 infer 关键字来推断模板字面量类型的部分:
type ExtractProp<T> = T extends `prop${infer R}` ? R : never;
type Prop1 = ExtractProp<'propA'>; // 'A'
type Prop2 = ExtractProp<'propB'>; // 'B'
type NotProp = ExtractProp<'button'>; // never模板字面量类型为 TypeScript 提供了强大的字符串操作能力, 使得我们可以在类型系统中进行复杂的字符串操作和模式匹配。这在创建类型安全的 API、处理字符串常量、实现复杂的字符串转换等场景中非常有用。