TypeScript 5.x 类型体操实战

2026-05-20
TypeScript前端

引言

TypeScript 的类型系统是图灵完备的。这意味着你可以在类型层面做几乎任何事情。但"可以做"不等于"应该做"——本文分享几个实用的类型技巧。

条件类型实战

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

type A = IsString<"hello">; // true
type B = IsString<42>;      // false

条件类型的真正威力在于配合泛型使用:

type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object
    ? DeepReadonly<T[K]>
    : T[K];
};

模板字面量类型

这是 TypeScript 4.1 引入的特性,在处理字符串模式匹配时非常强大:

type EventName<T extends string> = `on${Capitalize<T>}`;

type ClickEvent = EventName<"click">; // "onClick"
type ChangeEvent = EventName<"change">; // "onChange"

实用技巧:类型安全的 EventEmitter

type EventMap = {
  click: { x: number; y: number };
  change: { value: string };
};

class TypedEmitter<T extends Record<string, any>> {
  on<K extends keyof T>(event: K, handler: (data: T[K]) => void) {}
  emit<K extends keyof T>(event: K, data: T[K]) {}
}

总结

类型体操不是为了炫技,而是为了让代码在编译时就排除更多错误。记住:好的类型定义应该是自然而然的,而不是让人费解的谜题。


加载中...