TypeScript 类型体操与实战技巧
本文由一缘原创整理,专注于 TypeScript 类型系统的进阶玩法与实战技巧,涵盖类型体操、类型推断、条件类型、实用技巧,适合所有 TS/前端开发者。
TypeScript 类型体操与实战技巧
TypeScript 类型系统极其强大,掌握类型体操能让你写出更安全、灵活的代码。
1. 条件类型与类型推断
type IsString<T> = T extends string ? true : false;
type A = IsString<'abc'>; // true
type B = IsString<123>; // false
输出:
A = true
B = false
2. infer 关键字的妙用
type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type R1 = GetReturnType<() => number>; // number
type R2 = GetReturnType<(x: string) => boolean>; // boolean
输出:
R1 = number
R2 = boolean
3. 映射类型与递归类型
type DeepReadonly<T> = {
readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
};
type Obj = { a: { b: { c: number } }, d: string };
type ReadonlyObj = DeepReadonly<Obj>;
输出:
ReadonlyObj = {
readonly a: { readonly b: { readonly c: number } };
readonly d: string;
}
4. 联合类型与分布式条件类型
type ToArray<T> = T extends any ? T[] : never;
type A = ToArray<string | number>;
输出:
A = string[] | number[]
5. 类型体操实战:实现 Pick、Exclude、Parameters
5.1. 手写 Pick
type MyPick<T, K extends keyof T> = {
[P in K]: T[P];
};
type Obj = { a: number; b: string; c: boolean };
type Picked = MyPick<Obj, 'a' | 'c'>;
输出:
Picked = { a: number; c: boolean }
5.2. 手写 Exclude
type MyExclude<T, U> = T extends U ? never : T;
type E = MyExclude<'a' | 'b' | 'c', 'a' | 'c'>;
输出:
E = 'b'
5.3. 手写 Parameters
type MyParameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
type P = MyParameters<(x: number, y: string) => void>;
输出:
P = [number, string]
6. 字符串字面量类型与模板字符串类型
type EventName<T extends string> = `on${Capitalize<T>}`;
type Click = EventName<'click'>; // 'onClick'
type Hover = EventName<'hover'>; // 'onHover'
输出:
Click = 'onClick'
Hover = 'onHover'
7. 实战技巧:类型安全的 API 响应处理
interface ApiResponse<T> {
code: number;
data: T;
msg: string;
}
type User = { id: number; name: string };
type UserRes = ApiResponse<User>;
输出:
UserRes = { code: number; data: { id: number; name: string }; msg: string }
8. 类型体操进阶:深度可选 DeepPartial
type DeepPartial<T> = {
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};
type Obj = { a: { b: { c: number } }, d: string };
type PartialObj = DeepPartial<Obj>;
输出:
PartialObj = {
a?: { b?: { c?: number } };
d?: string;
}
9. 类型体操题目推荐
- 实现 PromiseAll 类型推断
- 实现 Chainable Options
- 实现 TupleToObject
- 实现 LastOfArray
(可在 type-challenges 找到更多练习)
10. 总结与最佳实践
- 善用类型推断、条件类型、映射类型提升类型安全
- 类型体操能极大提升 TS 代码的健壮性和灵活性
- 推荐多做 type-challenges 练习,提升类型系统掌控力