模板字符串类型可动态生成联合类型,适用于类名等规律性字符串;通过字面量类型与联合类型拼接,支持多级组合、条件插入及格式校验,但需用as const确保类型推导有效。

模板字符串类型(Template Literal Types)在 TypeScript 中可用于动态生成联合类型,尤其适合构建类名、CSS 类、API 路径等具有规律性结构的字符串类型。要动态拼接并生成新的类名联合类型,核心是结合字面量类型、联合类型与模板字符串类型进行类型推导。
基础用法:从固定前缀 + 可变后缀生成类名联合
假设你有一组状态后缀(如 "primary"、"secondary"、"danger"),想生成形如 "btn-primary"、"btn-secondary" 的类名联合类型:
type ButtonVariant = "primary" | "secondary" | "danger";
type ButtonClass = `btn-${ButtonVariant}`;
此时 ButtonClass 的类型等价于:
"btn-primary" | "btn-secondary" | "btn-danger"
多级拼接:组合多个联合类型
当类名由多个可变部分构成(如 size + variant + state),直接嵌套模板字符串即可,TypeScript 会自动计算所有组合:
type Size = "sm" | "md" | "lg";type Variant = "solid" | "outline";type State = "" | "-hover" | "-focus";type BadgeClass = `badge-${Size}-${Variant}${State}`;
结果是 3 × 2 × 3 = 18 种组合,例如:"badge-sm-solid-hover"、"badge-lg-outline-focus" 等。
条件插入:用条件类型控制片段是否出现
某些类名需根据上下文决定是否包含某段(如带或不带 disabled 后缀)。可用条件类型配合模板字符串实现“可选片段”:
type MaybeDisabled<t extends string> = T | `${T}-disabled`;
type InteractiveClass<t extends string> = `${T}-active` | `${T}-hover` | MaybeDisabled;</t></t>
或者更通用写法:
type WithDisabled<t extends string> = `${T}` | `${T}-disabled`;
type InputClass = WithDisabled | WithDisabled;</t>
这样 InputClass 包含 "input"、"input-disabled"、"input-sm"、"input-sm-disabled"。
提取与约束:确保拼接结果符合预期格式
为防止非法字符串被赋值,可结合 extends 约束和 infer 提取逻辑校验结构:
type ValidClassName<s extends string> = S extends `${infer Prefix}-${infer Suffix}`
? Suffix extends "primary" | "secondary" | "danger"
? S
: never
: never;
// 使用示例(编译时校验)
type MyClass = ValidClassName; // ✅ ok
type BadClass = ValidClassName; // ❌ error</s>
也可封装成工具类型,用于运行时类型守卫(配合 as const 和类型断言)。
不复杂但容易忽略的是:模板字符串类型只对字面量类型或其联合有效;若输入是 string 或未标注的变量,将退化为 string,失去联合推导能力。务必用 as const 或显式字面量类型定义源头。











