TypeScript 高级类型体操实战

·

TypeScript 高级类型体操实战

TypeScript 的类型系统是图灵完备的,这意味着你可以用它来表达几乎任何类型约束。本文将分享一些实用的高级类型模式。

条件类型

条件类型允许根据条件选择不同的类型:

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

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

实用的条件类型示例

// 提取 Promise 的内部类型
type Awaited<T> = T extends Promise<infer U> ? U : T;

type Result = Awaited<Promise<string>>; // string

模板字面量类型

TypeScript 4.1 引入的模板字面量类型非常强大:

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

type ClickEvent = EventName<'click'>; // 'onClick'
type FocusEvent = EventName<'focus'>; // 'onFocus'

实际应用:类型安全的事件系统

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

type EventHandler<K extends keyof EventMap> = 
  (event: EventMap[K]) => void;

type EventSystem = {
  [K in keyof EventMap as `on${Capitalize<K>}`]: EventHandler<K>;
};

// 结果类型:
// {
//   onClick: (event: { x: number; y: number }) => void;
//   onFocus: (event: { target: string }) => void;
//   onChange: (event: { value: string }) => void;
// }

映射类型进阶

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

// 深层 Partial
type DeepPartial<T> = {
  [K in keyof T]?: T[K] extends object
    ? DeepPartial<T[K]>
    : T[K];
};

实用工具类型

// 提取函数返回类型中的 Promise 值
type UnwrapPromise<T> = T extends Promise<infer U> 
  ? UnwrapPromise<U> 
  : T;

// 使某些属性变为可选
type PartialBy<T, K extends keyof T> = 
  Omit<T, K> & Partial<Pick<T, K>>;

// 使某些属性变为必选
type RequiredBy<T, K extends keyof T> = 
  Omit<T, K> & Required<Pick<T, K>>;

总结

TypeScript 的类型系统是前端工程化的重要基石。掌握高级类型不仅能写出更安全的代码,还能提供更好的开发体验。


类型即文档,类型即约束,类型即自由。

← 返回文章列表