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 的类型系统是前端工程化的重要基石。掌握高级类型不仅能写出更安全的代码,还能提供更好的开发体验。
类型即文档,类型即约束,类型即自由。