一、TypeScript类型系统的图灵完备性
TypeScript的类型系统是图灵完备的——这意味着你可以在类型层面实现任意复杂的逻辑。这是TS与Java/C#等传统静态类型语言的根本差异:TS的类型系统不是"附加的约束",而是一门独立的编程语言,运行在编译时而非运行时。
类型体操的意义不只是炫技——精确的类型定义可以在编译期捕获整类bug,并通过IDE的智能提示大幅提升开发体验。一个精心设计的类型可以让API的误用率降低80%以上。
二、条件类型与infer推断
条件类型是TS类型编程的if-else:T extends U ? X : Y。当T为联合类型时,分布式条件类型会自动遍历联合成员:T extends string ? T : never(当T为'abc'|123时,结果为'abc')。
infer关键字是类型体操的杀手锏——它可以在条件类型中声明类型变量,从类型结构中"提取"子类型:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never——提取函数返回类型type ArrayItem<T> = T extends (infer U)[] ? U : never——提取数组元素类型type PromiseValue<T> = T extends Promise<infer V> ? V : never——提取Promise包裹的值类型
三、模板字面量类型
TS 4.1引入的模板字面量类型(Template Literal Types)将字符串操作带入类型系统:
| 类型定义 | 示例输入 | 示例输出 |
|---|---|---|
type EventName<T> = `on${Capitalize<T>}` | 'click' | 'onClick' |
type CSSProp = `${'margin'|'padding'}${''|'Top'|'Right'|'Bottom'|'Left'}` | - | marginTop | paddingLeft 等8种 |
type Route<T> = `/api/${T}/${string}` | 'users' | '/api/users/xxx' |
四、映射类型与Key Remapping
映射类型(Mapped Types)可以基于已有类型生成新类型:
- Readonly / Partial / Required / Pick:内置工具类型,覆盖90%日常需求
- Key Remapping(TS 4.1+):通过as子句重映射键名:
type Getters<T> = { [P in keyof T as `get${Capitalize<string & P>}`]: () => T[P] }
这行代码自动为任意类型生成Getter接口——从{name: string}生成{getName: () => string}
五、实战模式与类型安全
5.1 Builder模式
利用联合类型+类型收窄实现类型安全的Builder模式:必填字段未设置时,返回对象类型不包含build方法,迫使调用方必须在设置全部必填字段后才能构建对象。
5.2 递归类型
type DeepReadonly<T> = { readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P] }
这个递归类型可以确保对象的所有嵌套层级都是只读的,是Immutable数据流的类型基石。
5.3 类型安全的路由
通过模板字面量类型+条件类型,可以在编译期验证API路径、Query参数的正确性,杜绝运行时404或参数类型不匹配。
评论 (36)