TypeScript 模板字面量类型详解

模板字面量类型(TS 4.1+)在编译期拼装与校验字符串:GET /users/:id 成为类型。本文讲解语法、联合类型组合爆炸与实战模式。

最佳实践
类型结构与组件组合插画

模板字面量类型用反引号语法在类型层拼字符串:type Event = \on${Capitalize}``。它与联合类型组合产生笛卡尔积,让"合法字符串集合"成为精确类型——API 路径、事件名、CSS 单位的类型化都靠它。

解决什么问题

字符串参数的真实约束往往是格式:size 只能是 'sm'|'md'|'lg' 与方向的组合、事件名必须是 on 开头。运行时校验太晚——模板字面量类型把格式约束提到编译期。

基础语法

type Size = 'sm' | 'md' | 'lg';
type Direction = 'top' | 'bottom';

// 组合爆炸:3 × 2 = 6 个合法值
type MarginClass = `margin-${Direction}-${Size}`;
// 'margin-top-sm' | 'margin-top-md' | ... | 'margin-bottom-lg'

function setMargin(cls: MarginClass) { /* ... */ }
setMargin('margin-top-sm');    // ✓
setMargin('margin-top-xl');    // ✗ 编译错误

内置字符串变换类型

type EventName<T extends string> = `on${Capitalize<T>}`;
type A = EventName<'click'>;   // 'onClick'

// 四个内置:Capitalize / Uncapitalize / Uppercase / Lowercase
type EnvKey = `APP_${Uppercase<'apiUrl' | 'timeout'>}`;
// 'APP_APIURL' | 'APP_TIMEOUT'

实战:类型安全的 API 客户端

type HttpMethod = 'GET' | 'POST' | 'DELETE';
type Endpoint = '/users' | '/posts' | `/users/${number}`;

function request(method: HttpMethod, path: Endpoint) { /* ... */ }

request('GET', '/users/42');   // ✓
request('GET', '/unknwon');    // ✗ 编译期拦截

路由合法性的编译期保障——重构路由时所有调用点自动受检。

进阶:infer 模式匹配

模板字面量类型可反向解构:

type ParseRoute<T> = T extends `/users/${infer Id}` ? { userId: Id } : never;
type R = ParseRoute<'/users/42'>;   // { userId: '42' }

字符串的"编译期正则"——配合递归模板类型可解析复杂格式(类型体操的主战场,适度使用)。

常见问题(FAQ)

Q:组合爆炸会拖慢编译吗?

会的——联合类型交叉组合数千个成员后编译器变慢。控制组合规模(单类型联合成员数百内),超大枚举考虑运行时校验。

Q:能校验数字格式吗(如 ID 必须数字串)?

可以间接实现:${number} 匹配任意数字字面量。复杂格式(邮箱正则)超出能力——那是运行时校验(Zod pattern)的职责。

Q:和 as const 数组的 keyof 方案比?

模板字面量类型表达"模式"(无限集合的规律),联合类型枚举"清单"(有限集合)。格式约束用前者,枚举值用后者。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台