第8章:类型系统进阶
条件类型(Conditional Types)
1. 基本概念
条件类型(Conditional Types)是 TypeScript 2.8 引入的高级类型特性,它允许基于类型关系进行条件分支判断,语法形式类似于三元表达式:T extends U ? X : Y
其中:
T是被检查的类型U是条件类型X是满足条件时的返回类型Y是不满足条件时的返回类型
2. 工作原理
type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>; // true
type B = IsString<number>; // false
条件类型会触发 分布式条件类型(Distributive Conditional Types) 特性:当传入联合类型时,会按成员逐个判断:
type ToArray<T> = T extends any ? T[] : never;
type StrOrNumArray = ToArray<string | number>; // string[] | number[]
3. 常用内置条件类型
TypeScript 内置了基于条件类型的工具类型:
Exclude<T, U>: 从 T 中排除可赋值给 U 的类型type T = Exclude<"a" | "b" | "c", "a">; // "b" | "c"Extract<T, U>: 从 T 中提取可赋值给 U 的类型NonNullable<T>: 排除 null 和 undefined
4. 类型推断(infer 关键字)
通过 infer 可以在条件类型中声明临时类型变量:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
function foo() { return 42; }
type FooReturn = ReturnType<typeof foo>; // number
5. 实际应用场景
5.1 API 响应类型处理
type ApiResponse<T> = {
success: true;
data: T;
} | {
success: false;
error: string;
};
type ExtractData<T> = T extends { success: true; data: infer D } ? D : never;
5.2 递归条件类型(4.1+)
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};
type Nested = { a: { b: number } };
type ReadonlyNested = DeepReadonly<Nested>;
6. 注意事项
- 避免过度复杂的嵌套条件类型(可能影响编译性能)
- 条件类型在未实例化前是惰性求值的
- 结合
never类型可实现更精确的类型过滤
进阶技巧:条件类型常用于类型体操(Type Challenges)中解决复杂类型问题,是构建类型工具库的核心技术。
