TypeScript泛型 #
一、泛型基础 #
1.1 什么是泛型 #
泛型是一种创建可复用组件的方式,组件可以处理多种类型而不是单一类型。
typescript
function identity<T>(arg: T): T {
return arg;
}
const str = identity<string>('hello');
const num = identity(123);
1.2 为什么需要泛型 #
typescript
function identityAny(arg: any): any {
return arg;
}
const result = identityAny('hello');
result.toUpperCase();
function identity<T>(arg: T): T {
return arg;
}
const result2 = identity('hello');
result2.toUpperCase();
二、泛型函数 #
2.1 泛型函数定义 #
typescript
function identity<T>(arg: T): T {
return arg;
}
const output1 = identity<string>('hello');
const output2 = identity(123);
2.2 箭头函数 #
typescript
const identity = <T>(arg: T): T => {
return arg;
};
const identity2 = <T,>(arg: T): T => arg;
2.3 泛型函数类型 #
typescript
type Identity = <T>(arg: T) => T;
const identity: Identity = (arg) => {
return arg;
};
interface GenericIdentityFn {
<T>(arg: T): T;
}
2.4 多类型参数 #
typescript
function pair<K, V>(key: K, value: V): [K, V] {
return [key, value];
}
const p1 = pair('name', 'Alice');
const p2 = pair(1, 'first');
三、泛型接口 #
3.1 泛型接口定义 #
typescript
interface Box<T> {
value: T;
}
const stringBox: Box<string> = { value: 'hello' };
const numberBox: Box<number> = { value: 123 };
3.2 泛型方法 #
typescript
interface Container<T> {
value: T;
getValue(): T;
setValue(value: T): void;
}
class Box<T> implements Container<T> {
constructor(public value: T) {}
getValue(): T {
return this.value;
}
setValue(value: T): void {
this.value = value;
}
}
3.3 泛型函数类型接口 #
typescript
interface GenericFn {
<T>(arg: T): T;
}
interface GenericFn2<T> {
(arg: T): T;
}
const identity: GenericFn = (arg) => arg;
const identity2: GenericFn2<string> = (arg) => arg;
四、泛型约束 #
4.1 基本约束 #
typescript
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({ length: 10 });
logLength(123);
4.2 在泛型约束中使用类型参数 #
typescript
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: 'Alice', age: 25 };
const name = getProperty(user, 'name');
const age = getProperty(user, 'age');
getProperty(user, 'email');
4.3 检查key是否存在 #
typescript
function hasKey<T, K extends string>(obj: T, key: K): key is K & keyof T {
return key in obj;
}
const user = { name: 'Alice', age: 25 };
if (hasKey(user, 'name')) {
console.log(user.name);
}
4.4 使用类类型约束 #
typescript
function create<T>(c: { new (): T }): T {
return new c();
}
class User {
name = 'Default';
}
const user = create(User);
console.log(user.name);
4.5 多重约束 #
typescript
interface Serializable {
serialize(): string;
}
interface Cloneable {
clone(): this;
}
function process<T extends Serializable & Cloneable>(obj: T): void {
console.log(obj.serialize());
obj.clone();
}
五、泛型默认值 #
5.1 基本默认值 #
typescript
interface Container<T = string> {
value: T;
}
const container1: Container = { value: 'hello' };
const container2: Container<number> = { value: 123 };
5.2 复杂默认值 #
typescript
interface ApiResponse<T = any, E = Error> {
data: T;
error: E | null;
}
const response1: ApiResponse = { data: 'success', error: null };
const response2: ApiResponse<string, string> = { data: 'success', error: '' };
5.3 依赖默认值 #
typescript
interface Config<T, U = T[]> {
value: T;
items: U;
}
const config1: Config<string> = { value: 'hello', items: ['a', 'b'] };
const config2: Config<string, Set<string>> = { value: 'hello', items: new Set() };
六、泛型工具类型 #
6.1 Partial #
typescript
type Partial<T> = {
[P in keyof T]?: T[P];
};
interface User {
name: string;
age: number;
}
type PartialUser = Partial<User>;
const user: PartialUser = {
name: 'Alice'
};
6.2 Required #
typescript
type Required<T> = {
[P in keyof T]-?: T[P];
};
interface User {
name: string;
age?: number;
}
type RequiredUser = Required<User>;
const user: RequiredUser = {
name: 'Alice',
age: 25
};
6.3 Readonly #
typescript
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
interface User {
name: string;
age: number;
}
type ReadonlyUser = Readonly<User>;
const user: ReadonlyUser = {
name: 'Alice',
age: 25
};
user.name = 'Bob';
6.4 Pick #
typescript
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
interface User {
id: number;
name: string;
email: string;
}
type UserPreview = Pick<User, 'id' | 'name'>;
const preview: UserPreview = {
id: 1,
name: 'Alice'
};
6.5 Omit #
typescript
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
interface User {
id: number;
name: string;
password: string;
}
type PublicUser = Omit<User, 'password'>;
const publicUser: PublicUser = {
id: 1,
name: 'Alice'
};
6.6 Record #
typescript
type Record<K extends keyof any, T> = {
[P in K]: T;
};
type UserMap = Record<string, User>;
const users: UserMap = {
'user1': { id: 1, name: 'Alice', password: '123' },
'user2': { id: 2, name: 'Bob', password: '456' }
};
七、实用示例 #
7.1 类型安全的Object.keys #
typescript
function getKeys<T extends object>(obj: T): (keyof T)[] {
return Object.keys(obj) as (keyof T)[];
}
const user = { name: 'Alice', age: 25 };
const keys = getKeys(user);
7.2 类型安全的assign #
typescript
function assign<T extends object>(target: T, ...sources: Partial<T>[]): T {
return Object.assign(target, ...sources);
}
const user = { name: 'Alice', age: 25 };
const updated = assign({}, user, { age: 26 });
7.3 类型安全的fetch #
typescript
async function fetchJson<T>(url: string): Promise<T> {
const response = await fetch(url);
return response.json();
}
interface User {
id: number;
name: string;
}
const user = await fetchJson<User>('/api/users/1');
console.log(user.name);
7.4 类型安全的EventEmitter #
typescript
type EventMap = {
[key: string]: any;
};
class EventEmitter<T extends EventMap> {
private listeners: Map<keyof T, Function[]> = new Map();
on<K extends keyof T>(event: K, listener: (data: T[K]) => void): void {
if (!this.listeners.has(event)) {
this.listeners.set(event, []);
}
this.listeners.get(event)!.push(listener);
}
emit<K extends keyof T>(event: K, data: T[K]): void {
const listeners = this.listeners.get(event);
if (listeners) {
listeners.forEach(listener => listener(data));
}
}
}
interface MyEvents {
userCreated: { id: number; name: string };
userDeleted: number;
}
const emitter = new EventEmitter<MyEvents>();
emitter.on('userCreated', (data) => {
console.log(data.name);
});
emitter.emit('userCreated', { id: 1, name: 'Alice' });
八、总结 #
本章介绍了TypeScript泛型:
泛型类型 #
- 泛型函数
- 泛型接口
- 泛型类
- 泛型类型别名
泛型约束 #
- extends约束
- 多重约束
- 类型参数约束
最佳实践 #
- 使用泛型提高代码复用性
- 合理使用约束限制类型
- 为泛型参数提供默认值
- 使用内置工具类型简化开发
最后更新:2026-03-26