TypeScript 高级技巧:我常用的 8 个类型体操
大家好,我是蔓蔓。TypeScript 写得多了,自然会积累一些高级用法。今天整理了几个我日常开发中经常用到的类型体操技巧,希望能帮到大家。
1. Partial 的深层版本
type DeepPartial<T> = { [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]; }; interface User { name: string; address: { city: string; street: string; }; } type PartialUser = DeepPartial<User>; // { name?: string; address?: { city?: string; street?: string } }2. 函数参数提取
type Parameters<T> = T extends (...args: infer P) => any ? P : never; function greet(name: string, age: number): string { return `Hello ${name}, you are ${age}`; } type GreetParams = Parameters<typeof greet>; // [string, number]3. 条件类型与 infer
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any; type GreetReturn = ReturnType<typeof greet>; // string4. Omit 和 Pick 的组合使用
interface Post { id: number; title: string; content: string; createdAt: Date; } type PostPreview = Pick<Post, 'title' | 'id'>; type PostWithoutDate = Omit<Post, 'createdAt'>;5. 模板字面量类型
type EventName<T extends string> = `${T}Changed`; type ClickEvent = EventName<'click'>; // 'clickChanged' type FocusEvent = EventName<'focus'>; // 'focusChanged'6. 类型守卫
interface Bird { fly(): void; layEggs(): void; } interface Fish { swim(): void; layEggs(): void; } function isFish(pet: Fish | Bird): pet is Fish { return (pet as Fish).swim !== undefined; }7. 索引类型查询
interface User { id: number; name: string; email: string; } type UserKeys = keyof User; // 'id' | 'name' | 'email' type UserValues = User[keyof User]; // number | string8. 映射类型
type Readonly<T> = { readonly [P in keyof T]: T[P]; }; type Writable<T> = { -readonly [P in keyof T]: T[P]; }; type Nullable<T> = { [P in keyof T]: T[P] | null; };类型体操虽然有趣,但不要过度使用。团队协作中,可读性永远是第一位的。你有什么常用的 TypeScript 技巧吗?欢迎分享~