# 模板字面量(Template Literal Types)
该节讲解 TypeScript 在 字面量类型 扩充的模板字面量类型。
# 概述
模板字面量参考了 JavaScript 模板字面量语法 (opens new window) 基于字面量类型,生成复杂的联合类型
type World1 = "world";
type Greeting = `hello ${World1}`;插入的表达式中,可以使用 | 联合操作符,组合多个字符串。
模板字符串类型同样支持插入多个字面量集合类型,此时返回类型为各字面量集合类型的笛卡尔积 (opens new window)
type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`;
type Lang = "en" | "ja" | "pt";
// 等同于 type LocaleMessageIDs = "en_welcome_email_id" | "en_email_heading_id" | "en_footer_title_id" | "en_footer_sendoff_id" | "ja_welcome_email_id" | "ja_email_heading_id" | "ja_footer_title_id" | "ja_footer_sendoff_id" | "pt_welcome_email_id" | "pt_email_heading_id" | "pt_footer_title_id" | "pt_footer_sendoff_id"
type LocaleMessageIDs = `${Lang}_${AllLocaleIDs}`;由于联合类型不得超过 10万,所以当组合类型和插入模板过多时会导致联合类型超出限制。
type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
// TODO: 模板字面量类型,超出了联合类型 10 万的限制,会报错
type Zip = `${Digit}${Digit}${Digit}${Digit}${Digit}`;
# 结合查找类型
一个典型的案例是通过如下。
// 表单数据
const Form = {
firstName: "Saoirse",
lastName: "Ronan",
age: 26,
};
type Form = typeof Form;
type FormKey = keyof Form
// 定义监听表单字段变化的类型
type PropEventSource<Type> = {
on(eventName: `${FormKey}Changed`, cb: (newValue: any) => void): void;
};
function makeWatchedObject<Form>(obj: Form): Form & PropEventSource<Type> {
}
const person = makeWatchedObject(Form);
person.on("firstNameChanged", () => {});
// 报错,没有这个的变量变化
person.on("firstNameChanged1", () => {});
# 启发式字符串类型(Intrinsic string types)
- https://github.com/microsoft/TypeScript/pull/40580 (opens new window)
- https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html#intrinsic-string-manipulation-types (opens new window)
# 启发式字符串操作类型
TypeScript 内部实现了对字面量类型的格式化操作。
type Greeting = "Hello, world"
// Uppercase 将 Greeting 的字面量全部大写, ShoutyGreeting = "HELLO, WORLD"
type ShoutyGreeting = Uppercase<Greeting>
// Lowercase 将 Greeting 的字面量全部小写, ShoutyGreeting = "hello, world"
type ShoutyGreeting = Lowercase<Greeting>
// Capitalize 将 Greeting 的字面量首字母大写, ShoutyGreeting = "Hello, world"
type ShoutyGreeting = Capitalize<Greeting>
// Uncapitalize 将 Greeting 的字面量首字母小写, ShoutyGreeting = "hello, world"
type ShoutyGreeting = Uncapitalize<Greeting>TIP
注意这种类型是通过 TypeScript 内部指向 intrinsic 关键字,通过编译解析别名和内部映射的函数函数,实现的类型转义。
# 参考资料
← 原始类型-字面量类型 原始类型-枚举类型 →