类型推导的妙用
TypeScript 的类型推导能力远比我们想象的强大。善用 infer 关键字可以做到很多有趣的事情。
提取函数返回类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
function fetchUser() {
return { name: 'XC', age: 25 };
}
type User = ReturnType<typeof fetchUser>;
// { name: string; age: number }
提取 Promise 内部类型
type Awaited<T> = T extends Promise<infer U> ? Awaited<U> : T;
type Result = Awaited<Promise<Promise<string>>>;
// string
模板字面量类型
TypeScript 4.1 引入的模板字面量类型是一个强大的特性:
type EventName = `on${Capitalize<'click' | 'focus' | 'blur'>}`;
// 'onClick' | 'onFocus' | 'onBlur'
条件类型的实际应用
type IsArray<T> = T extends any[] ? true : false;
type A = IsArray<string[]>; // true
type B = IsArray<number>; // false
实用工具类型
DeepPartial
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
NonNullableKeys
type NonNullableKeys<T> = {
[K in keyof T]-?: undefined extends T[K] ? never : K;
}[keyof T];
总结
TypeScript 的类型系统是图灵完备的,理论上可以在类型层面做任何计算。当然,日常开发中我们不需要走那么极端,掌握这些实用技巧就足够了。
类型不是束缚,而是你的安全网。