我总是提醒自己一定要严谨严谨严谨
目录
- TypeScript 泛型 (Generics)
- 1. 什么是泛型?
- 2. 为什么需要泛型?
- 3. 泛型常见用法
- 3.1 函数泛型
- 3.2 接口泛型
- 3.3 类泛型
- 3.4 泛型约束
- 3.5 泛型默认值
- 3.6 多个泛型参数
- 4. 泛型应用场景
TypeScript 泛型 (Generics)
1. 什么是泛型?
泛型是一种在定义函数、类、接口时不预先指定具体类型,而在使用时再指定类型的机制。
作用:
- 提高代码复用性
- 保持类型安全
2. 为什么需要泛型?
示例:没有泛型的函数
function identity(arg: any): any {return arg;
}
问题:类型丢失(返回值是 any),类型不安全
使用泛型:
function identity<T>(arg: T): T {return arg;
}const num = identity<number>(123); // 类型推断为 number
const str = identity("hello"); // 类型推断为 string
3. 泛型常见用法
3.1 函数泛型
function getFirst<T>(arr: T[]): T {return arr[0];
}const firstNum = getFirst<number>([1, 2, 3]); // number
const firstStr = getFirst(["a", "b", "c"]); // string(类型推断)
3.2 接口泛型
interface ApiResponse<T> {code: number;data: T;message: string;
}const userResponse: ApiResponse<{ id: number; name: string }> = {code: 200,data: { id: 1, name: "Alice" },message: "success"
};
3.3 类泛型
class Stack<T> {private items: T[] = [];push(item: T) {this.items.push(item);}pop(): T | undefined {return this.items.pop();}
}const numberStack = new Stack<number>();
numberStack.push(1);const strStack = new Stack<string>();
strStack.push("a");
3.4 泛型约束
interface HasLength {length: number;
}function logLength<T extends HasLength>(arg: T): T {console.log(arg.length);return arg;
}logLength("hello"); // ✅ 字符串有 length
logLength([1, 2, 3]); // ✅ 数组有 length
// logLength(123); // ❌ number 没有 length
3.5 泛型默认值
function getValue<T = string>(value: T): T {return value;
}const v1 = getValue(123); // 推断为 number
const v2 = getValue(undefined); // 默认类型 string
说明:
- 如果传入值能推断类型,则用推断类型
- 如果无法推断,则使用泛型默认值
3.6 多个泛型参数
function mapPair<K, V>(key: K, value: V): [K, V] {return [key, value];
}const pair = mapPair("id", 123); // [string, number]
4. 泛型应用场景
- 集合类:如 Stack、Queue、Map 等
- 工具函数:如 identity、getFirst、mergeObjects
- 接口/类型定义:API 返回数据结构复用
- React / Vue Hooks:如 useState、ref
- 第三方库:如 Lodash、Axios 等
泛型 = 参数化的类型