TypeScript泛型编程指南
泛型是TypeScript中最强大也最令人困惑的特性之一。掌握泛型编程,可以编写出既类型安全又高度复用的代码。本文将从基础到进阶,系统讲解TypeScript泛型的使用方法和设计模式。
一、泛型基础
// 基本泛型函数
function identity<T>(arg: T): T {
return arg;
}
// 泛型接口
interface Repository<T> {
findById(id: string): Promise<T>;
findAll(): Promise<T[]>;
create(data: Omit<T, 'id'>): Promise<T>;
update(id: string, data: Partial<T>): Promise<T>;
delete(id: string): Promise<void>;
}
// 泛型类
class DataStore<T> {
private items: T[] = [];
add(item: T): void { this.items.push(item); }
get(index: number): T | undefined { return this.items[index]; }
getAll(): T[] { return [...this.items]; }
}
二、泛型约束
// extends约束
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(arg: T): T {
console.log(arg.length);
return arg;
}
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) {
return obj[key];
}
const user = { name: '张三', age: 25 };
getProperty(user, 'name'); // OK, 返回string
getProperty(user, 'age'); // OK, 返回number
getProperty(user, 'email'); // Error
三、条件类型与推断
// 条件类型
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
// infer关键字 - 类型推断
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type Parameters<T> = T extends (...args: infer P) => any ? P : never;
// 实用:提取Promise内部类型
type Unpacked<T> = T extends Promise<infer U> ? U : T;
type Result = Unpacked<Promise<string>>; // string
四、映射类型与工具类型
// 内置工具类型
type Partial<T> = { [K in keyof T]?: T[K] }; // 所有属性可选
type Required<T> = { [K in keyof T]-?: T[K] }; // 所有属性必需
type Readonly<T> = { readonly [K in keyof T]: T[K] }; // 所有属性只读
type Pick<T, K extends keyof T> = { [P in K]: T[P] }; // 选取部分属性
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; // 排除属性
// 自定义映射类型
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
// 将指定属性变为可选
type UserWithOptionalEmail = Optional<User, 'email' | 'phone'>;
type DeepPartial<T> = {
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};
五、泛型设计模式
// 工厂模式
type Constructor<T> = new (...args: any[]) => T;
function createInstance<T>(ctor: Constructor<T>, ...args: any[]): T {
return new ctor(...args);
}
// Builder模式
class QueryBuilder<T> {
private conditions: string[] = [];
where<K extends keyof T>(field: K, value: T[K]): this {
this.conditions.push(`${String(field)} = ${value}`);
return this;
}
build(): string { return this.conditions.join(' AND '); }
}
TypeScript泛型是一个强大的类型系统工具,掌握它可以极大地提升代码质量和开发体验。建议在实际项目中多练习,从简单的泛型函数开始,逐步过渡到复杂的条件类型和映射类型。