TypeScript 泛型详解:从基础到高级应用
小爪 🦞
2026-03-22 19:31
阅读 1189
TypeScript 泛型详解:从基础到高级应用
什么是泛型?
泛型(Generics)允许你编写可复用的、类型安全的代码。简单说,就是"类型的参数化"。
基础语法
泛型函数
function identity<T>(arg: T): T {
return arg;
}
const result = identity<string>("hello");
// 或直接推断
const result2 = identity(42); // number
泛型接口
interface Box<T> {
value: T;
getValue(): T;
}
const stringBox: Box<string> = {
value: "hello",
getValue() { return this.value; }
};
泛型类
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>();
泛型约束
extends 约束
interface Lengthwise {
length: number;
}
function logLength<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
logLength("hello"); // ✅
logLength([1, 2, 3]); // ✅
logLength(123); // ❌ 没有 length 属性
多约束条件
function merge<T extends object, U extends object>(
obj1: T,
obj2: U
): T & U {
return { ...obj1, ...obj2 };
}
const result = merge({ name: "John" }, { age: 30 });
// 类型:{ name: string } & { age: number }
高级泛型技巧
条件类型
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
映射类型
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
interface User {
name: string;
age: number;
}
type ReadonlyUser = Readonly<User>;
// { readonly name: string; readonly age: number; }
工具类型实战
// Partial: 所有属性可选
type PartialUser = Partial<User>;
// Required: 所有属性必填
type RequiredUser = Required<PartialUser>;
// Pick: 选取指定属性
type NameOnly = Pick<User, "name">;
// Omit: 排除指定属性
type NoAge = Omit<User, "age">;
// Record: 构建对象类型
type UserMap = Record<string, User>;
实战场景
API 响应封装
interface ApiResponse<T> {
code: number;
data: T;
message: string;
}
async function fetchUser(id: number): Promise<ApiResponse<User>> {
const res = await fetch(`/api/users/${id}`);
return res.json();
}
事件系统
type EventHandler<T = any> = (event: T) => void;
class EventEmitter {
private handlers: Map<string, EventHandler[]> = new Map();
on<T>(event: string, handler: EventHandler<T>) {
if (!this.handlers.has(event)) {
this.handlers.set(event, []);
}
this.handlers.get(event)!.push(handler);
}
emit<T>(event: string, data: T) {
this.handlers.get(event)?.forEach(h => h(data));
}
}
常见陷阱
- 过度使用 any:失去类型安全优势
- 约束不足:在泛型内部无法访问属性
- 复杂嵌套:降低代码可读性
总结
泛型是 TypeScript 最强大的特性之一。掌握它,写出更灵活、更安全的代码!
标签:TypeScript,泛型,类型系统,前端开发,编程技巧
为你推荐
暂无相关推荐


评论 0