第6章:泛型
泛型函数与泛型接口
1. 泛型函数的基本用法
泛型函数允许在定义函数时不预先指定具体类型,而是在调用时动态确定类型。语法如下:
function identity<T>(arg: T): T {
return arg;
}
// 调用时显式指定类型
let output1 = identity<string>("Hello");
// 通过类型推断自动确定类型
let output2 = identity(42); // 推断为 number
2. 多类型参数的泛型函数
可以定义多个类型参数,用逗号分隔:
function merge<U, V>(obj1: U, obj2: V): U & V {
return { ...obj1, ...obj2 };
}
const result = merge({ name: "Alice" }, { age: 30 });
3. 泛型接口的定义
接口也可以使用泛型,增强其灵活性:
interface KeyValuePair<K, V> {
key: K;
value: V;
}
let pair1: KeyValuePair<number, string> = { key: 1, value: "One" };
let pair2: KeyValuePair<string, boolean> = { key: "enabled", value: true };
4. 泛型约束函数参数
通过 extends 约束泛型类型范围:
interface Lengthwise {
length: number;
}
function logLength<T extends Lengthwise>(arg: T): void {
console.log(arg.length);
}
logLength("text"); // OK,字符串有 length 属性
logLength([1, 2, 3]); // OK,数组有 length 属性
logLength(42); // 错误:数字没有 length 属性
5. 泛型接口与函数结合
泛型接口可以描述函数类型:
interface GenericFunc<T> {
(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericFunc<number> = identity; // 限定为 number 类型
6. 实际应用场景
- API 响应处理:统一处理不同数据结构的响应
- 工具函数库:如 Lodash 风格的通用函数
- 集合操作:实现类型安全的 map/filter/reduce
7. 注意事项
- 避免过度使用泛型导致代码可读性下降
- 优先使用类型推断简化调用语法
- 在复杂场景中合理使用泛型约束
最佳实践:当函数或接口需要处理多种类型但逻辑相同时,泛型是最佳选择。对于完全无关的类型,建议使用函数重载或联合类型。
