TypeScript泛型:真实代码的实用模式

TypeScript泛型是类型系统最强大的特性之一——也是最常被误解的之一。许多开发人员要么避免泛型(改为写`any`),要么用他们不需要的泛型过度工程化。本指南专注于在日常TypeScript代码中出现的实用模式以及它们解决的具体问题。

泛型是什么以及何时需要它们

泛型解决的核心问题:编写在多种类型上一致工作同时保留类型信息的函数。没有泛型:
“`typescript
function identity(value: any): any { return value; }
const result = identity(42); // result: any — 类型信息丢失
“`
有泛型:
“`typescript
function identity(value: T): T { return value; }
const result = identity(42); // result: number — 类型保留
“`
`T`是一个类型参数——在调用时将被指定(或推断)的类型占位符。何时使用泛型:当你需要一个在类型上一致工作同时保留类型信息的函数或类时;当你正在构建可复用的工具类型时;当函数的返回类型取决于输入类型时。何时不使用泛型:当`unknown`(类型检查但未知)或联合类型(如`string | number`)就足够时;当类型总是相同时。过度泛型是一种常见的反模式——如果一个函数只接受并返回字符串,它就不应该是泛型的。最重要的泛型模式:泛型函数(如上所示)、泛型接口、泛型类型别名和泛型约束。

实用泛型模式

泛型约束(`extends`):约束泛型可以是什么类型。最常见的模式:
“`typescript
function getProperty(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: “Alice”, age: 30 };
const name = getProperty(user, “name”); // string — 自动补全有效
// getProperty(user, “email”) 在编译时会报错
“`
这是`keyof`模式——TypeScript表达”T类型某个键的字符串”的方式。返回类型`T[K]`是”索引访问类型”——TypeScript将其解析为实际的属性类型。用于数据结构的泛型接口:
“`typescript
interface ApiResponse {
data: T;
status: number;
message: string;
}
type UserResponse = ApiResponse; // data: User
type PostsResponse = ApiResponse; // data: Post[]
“`
这种模式在API客户端代码中无处不在。`Awaited`工具类型解包Promise:`Awaited>`= `string`。带泛型的条件类型:
“`typescript
type IsArray = T extends any[] ? true : false;
type A = IsArray; // true
type B = IsArray; // false
“`
条件类型中的`infer`关键字:
“`typescript
type UnpackPromise = T extends Promise ? U : T;
type Unpacked = UnpackPromise>; // string
type Direct = UnpackPromise; // number
“`
`infer U`表示”如果T是一个Promise,将包装的类型推断到U中”。这就是`Awaited`、`ReturnType`和`Parameters`等工具类型在内部工作的方式。映射类型(转换类型中的每个键):
“`typescript
type Partial = { [K in keyof T]?: T[K] }; // 内置
type Readonly = { readonly [K in keyof T]: T[K] }; // 内置
type Stringify = { [K in keyof T]: string };
“`
内置工具类型(`Partial`、`Required`、`Readonly`、`Pick`、`Omit`、`Record`、`ReturnType`、`Parameters`)都是在内部用泛型和映射/条件类型实现的——理解它们是阅读复杂TypeScript类型签名的关键。

上一篇 TypeScript Generics: Practical Patterns for Real Code
下一篇 Vienna: Empire, Coffee Houses, and the World's Best Museums