首页 / TypeScript 入门教程 / 模板字面量类型

TypeScript 入门教程

模板字面量类型

本教程共 80 篇 · 第 48 篇 · 更新于 2026-08-10 · 约 10 分钟阅读

TypeScriptTypeScript 入门教程模板字面量Template Literal字符串类型

本节目标:学会用模板字面量类型在类型层面拼接字符串,利用联合类型的自动展开生成精确的字符串联合,以及用内置的 Uppercase/Lowercase 等工具类型处理大小写。

类型里的字符串拼接

JavaScript 有模板字符串 `Hello ${name}`,TypeScript 把同样的能力搬到了类型系统里:

type World = "world";
type Greeting = `Hello ${World}`; // "Hello world"

Greeting 的类型不是 string,而是精确的字面量 "Hello world"。这和 JavaScript 的模板字符串直觉一致,只是它发生在编译期的类型层面。

为什么要这东西

实际开发中,有很多字符串是有固定格式的:onClickgetUsersbtn-primary-lg。用 string 类型太宽泛,用字面量手动拼太麻烦。模板字面量类型解决的正是这个痛点——用规则生成精确的字符串类型。

联合类型的笛卡尔积

这是模板字面量类型最神奇的行为:当插值位置是一个联合类型时,TypeScript 会自动生成所有可能的组合

type Size = "sm" | "md" | "lg";
type Variant = "primary" | "secondary";

// 自动展开为 3 × 2 = 6 种组合
type BtnClass = `btn-${Variant}-${Size}`;
// "btn-primary-sm" | "btn-primary-md" | "btn-primary-lg"
// | "btn-secondary-sm" | "btn-secondary-md" | "btn-secondary-lg"

每个联合成员都和其他联合成员各组合一次——这就是笛卡尔积。TypeScript 替你算好了所有可能的字符串,你只需要关心结果就行。

不过有个提醒:联合成员太多会导致类型膨胀。比如两个各有 10 个成员的联合组合,生成 100 种字面量——编辑器可能会卡。

内置字符串操作类型

TypeScript 提供了四个内置的”字符串方法”,但它们在类型层面运行,不产生运行时开销:

类型作用示例
Uppercase<T>全大写Uppercase<"hello">"HELLO"
Lowercase<T>全小写Lowercase<"HELLO">"hello"
Capitalize<T>首字母大写Capitalize<"hello">"Hello"
Uncapitalize<T>首字母小写Uncapitalize<"Hello">"hello"

这些工具类型只接受 string 的子类型,不能用于 numberboolean

实际用法

事件名生成

前端框架里到处都是 onClickonSubmitonChange 这种事件名。用模板字面量类型可以保证事件名格式统一:

type EventName = "click" | "submit" | "change" | "focus";
// 自动生成 on 开头的事件类型
type Handler = `on${Capitalize<EventName>}`;
// "onClick" | "onSubmit" | "onChange" | "onFocus"

如果有人写了 "onclick"(小写 c),TypeScript 会直接报错——省了一个 ESLint 规则。

API 路径类型

type HttpMethod = "get" | "post" | "put" | "delete";
type Resource = "users" | "posts" | "comments";

// 自动生成所有 API 端点
type Endpoint = `/${HttpMethod}/${Resource}`;
// "/get/users" | "/get/posts" | ... 共 12 种组合

虽然实际项目不会把所有端点列成一个联合类型,但这个模式展示了模板字面量类型的精确表达能力。

自定义工具类型

// 给任意字符串加前缀
type Prefixed<T extends string, P extends string> = `${P}${Capitalize<T>}`;

type Action = Prefixed<"save", "on">;       // "onSave"
type Action2 = Prefixed<"delete", "handle">; // "handleDelete"

与 infer 的预告

模板字面量类型和 infer 配合可以实现类型层面的字符串匹配和解析,比如用 `${infer First}-${infer Last}` 从联合类型中拆分字符串。下一章 infer 会详细讲这个。

小结

  • `${A}${B}` 在类型层面拼接字符串,结果是精确的字面量类型
  • 联合类型做插值时会自动展开成笛卡尔积——注意成员多的场景
  • Uppercase / Lowercase / Capitalize / Uncapitalize 是类型层的字符串操作
  • 适用于事件名、API 路径、CSS 类名等有固定格式的字符串场景