TypeScript 泛型:解锁灵活且安全的代码重用
在 TypeScript 中,泛型(Generics)是提升代码复用性和类型安全的核心利器。它允许我们编写可适应多种类型的组件,而非重复的冗余代码。
为什么需要泛型?
假设需要一个返回数组首元素的函数:
function getFirst(arr: number[]): number {
return arr[0];
}
但若需支持 string[],只能重写函数——这违反了 DRY(Don't Repeat Yourself)原则。泛型通过类型变量解决此问题:
function getFirst<T>(arr: T[]): T {
return arr[0];
}
// 自动推断类型
const num = getFirst([1, 2]); // T = number
const str = getFirst(["a", "b"]); // T = string
泛型的核心优势
- 类型安全:
- 避免
any的运行时风险,编译器会检查类型一致性。
- 避免
- 代码复用:
- 一套逻辑适配多种类型(数组、API 响应、状态管理等)。
- 智能推断:
- TS 能自动推导泛型类型,减少手动标注。
进阶应用
泛型约束:限制类型范围
interface HasLength {
length: number }
function logLength<T extends HasLength>(obj: T): void {
console.log(obj.length);
}
logLength("hello"); // ✅ 字符串有 length
logLength(42); // ❌ 数字无 length,编译报错
泛型接口:定义灵活的数据结构
interface ApiResponse<T> {
data: T;
error: string | null;
}
const userRes: ApiResponse<{
name: string }> = ...;
const postRes: ApiResponse<{
title: string }> = ...;
实践建议
- 避免过度泛化:仅在需要多类型支持时使用。
- 明确约束:用
extends确保类型符合预期行为。 - 结合工具类型:如
Partial<T>、Pick<T, K>增强灵活性。
总结
泛型让 TypeScript 在静态类型与灵活性间取得完美平衡。掌握泛型,你将写出更简洁、健壮且易于扩展的代码,彻底告别重复劳动!