TypeScript 泛型 extends 约束与条件类型详解
请解释 TypeScript 中泛型约束 extends 的用法(约束类型参数),以及条件类型(Conditional Types)T extends U ? X : Y 的原理与嵌套使用。
回答
古法程序员
泛型约束(Generic Constraints):
// 约束 T 必须有 length 属性
function logLength<T extends { length: number }>(arg: T): number {
return arg.length;
}
logLength('hello'); // ok
logLength([1,2,3]); // ok
// logLength(123); // Error: number 没有 length
// keyof 约束
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
条件类型(Conditional Types):
type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>; // true
type B = IsString<123>; // false
// 分布式条件类型(naked type parameter)
type ToArray<T> = T extends unknown ? T[] : never;
type C = ToArray<string | number>; // string[] | number[]
// 若 T 是联合类型且是裸类型参数,条件类型自动分布式执行
嵌套条件类型:
type TypeName<T> =
T extends string ? 'string' :
T extends number ? 'number' :
T extends boolean ? 'boolean' :
T extends undefined ? 'undefined' :
T extends null ? 'null' :
T extends Function ? 'function' :
'object';
实用技巧:
- 用
[T] extends [U]包装可关闭分布式(保持联合类型整体判断) infer关键字用于在条件类型中提取类型变量