TypeScript泛型:从令人困惑到有用

TypeScript泛型是语言最强大的功能之一,也是不熟悉类型语言的开发者最困惑的功能之一。以下是从概念到实际应用的清晰渐进。

泛型解决的问题

没有泛型,你面临选择:为每种类型编写相同逻辑(重复的)、使用any(丢失类型安全),或使用unknown(需要类型转换)。泛型让你编写适用于任何类型的代码,同时在操作过程中保留类型信息。

// 没有泛型——丢失类型信息
function firstItem(arr: any[]): any { return arr[0]; }
const item = firstItem([1, 2, 3]); // item: any — TypeScript不知道它是数字

// 有泛型——类型信息被保留
function firstItem(arr: T[]): T { return arr[0]; }
const item = firstItem([1, 2, 3]); // item: number — TypeScript知道
const str = firstItem(['a', 'b']); // str: string

类型约束

泛型可以使用extends约束以要求特定属性:

interface HasId { id: number; }

function getById(items: T[], id: number): T | undefined {
  return items.find(item => item.id === id);
}
// 现在TypeScript知道T有.id——如果你传递没有id的对象会报错

泛型接口和类型

interface ApiResponse {
  data: T;
  status: number;
  message: string;
}

type UserResponse = ApiResponse;
type PostResponse = ApiResponse;
// UserResponse.data是User;PostResponse.data是Post[]

泛型值得用的情况

使用泛型用于:处理集合的工具函数(filter、map、sort)、共享数据结构(树、队列、结果类型)、API响应包装器,以及变化的React组件prop类型。不要使用泛型用于:只处理一种类型的函数、有固定props的组件,或任何有更简单方案明显的情况。过度使用泛型产生技术上正确但比必要更难读的代码。

上一篇 TypeScript Generics: From Confusing to Useful
下一篇 The German Christmas Market Circuit: Which Ones Are Worth It