TypeScript 高级类型体操实战

从条件类型、映射类型到类型推断,掌握 TS 类型编程的核心工具,写出类型安全的通用代码。

TypeScript 的类型系统足够强大,强大到可以「编程」。本文介绍类型体操的核心工具与实战场景。

为什么需要类型体操

当你要写通用库或复杂工具函数时,普通的类型标注不够,需要「根据输入类型推导出输出类型」。类型体操就是让类型随逻辑联动。

核心工具

条件类型(Conditional Types)

根据类型做「分支」:

type IsString<T> = T extends string ? true : false;

映射类型(Mapped Types)

遍历对象类型,逐属性变换:

type Readonly<T> = { readonly [K in keyof T]: T[K] };

keyof 与索引访问

提取键与值类型:

type Keys = keyof { a: 1; b: 2 }; // 'a' | 'b'

infer 推断

在条件类型中「提取」类型:

type ReturnType<T> = T extends (...args: any) => infer R ? R : never;

一个实战案例

实现一个「根据路径取嵌套值」的类型安全函数:

type Get<T, P extends string> =
  P extends `${infer K}.${infer Rest}`
    ? K extends keyof T ? Get<T[K], Rest> : never
    : P extends keyof T ? T[P] : never;

function get<T, P extends string>(obj: T, path: P): Get<T, P> {
  /* 实现略 */
}

现在 get(user, 'profile.name') 能精确推导出 string 类型。

实用建议

  • 适度使用:类型体操是为了安全与体验,过度炫技反而难维护;
  • 善用内置工具类型:Partial、Pick、Omit 等多数场景已够用;
  • 可读性优先:复杂类型拆成小步,比一行天书更好维护。

结语

类型体操的本质是「让类型系统帮你表达约束」。掌握核心工具,你就能在保持类型安全的同时,写出更通用、更优雅的代码。