# 模板字面量(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)

# 启发式字符串操作类型

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 关键字,通过编译解析别名和内部映射的函数函数,实现的类型转义。

# 参考资料