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泛型:

泛型类型 #

  1. 泛型函数
  2. 泛型接口
  3. 泛型类
  4. 泛型类型别名

泛型约束 #

  1. extends约束
  2. 多重约束
  3. 类型参数约束

最佳实践 #

  1. 使用泛型提高代码复用性
  2. 合理使用约束限制类型
  3. 为泛型参数提供默认值
  4. 使用内置工具类型简化开发
最后更新:2026-03-26