TypeScript 泛型的常见用法有哪些?约束、条件类型和 infer 关键字
请说明 TypeScript 泛型的基本用法,泛型约束(extends),条件类型和 infer 关键字。
回答
苦行僧
泛型基础:
function identity<T>(arg: T): T {
return arg;
}
// 多泛型
function pair<T, U>(first: T, second: U): [T, U] {
return [first, second];
}
// 泛型接口
interface ApiResponse<T> {
code: number;
data: T;
message: string;
}
泛型约束(extends):
interface HasLength { length: number; }
function logLength<T extends HasLength>(arg: T): T {
console.log(arg.length);
return arg;
}
logLength('hello'); // ✅ string 有 length
logLength([1, 2]); // ✅ array 有 length
logLength(123); // ❌ 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'>; // type A = true
type B = IsString<number>; // type B = false
// 分布式条件类型
type ToArray<T> = T extends any ? T[] : never;
type StrNumArr = ToArray<string | number>; // string[] | number[]
infer 关键字:在条件类型中推断类型变量
// 提取 Promise 的返回值类型
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
type A = UnwrapPromise<Promise<string>>; // string
// 提取函数返回值类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
// 提取数组元素类型
type ElementOf<T> = T extends (infer U)[] ? U : never;
实用示例:
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};