Typescript 泛型的定义和使用范围

在 TypeScript 中,你可以在定义类型时使用泛型。泛型允许你创建可重用的类型定义,这些类型定义可以根据传入的类型参数进行调整。这使得类型定义更加灵活和强大。

泛型类型定义

1. 基本语法

你可以使用 <T>(或其他任何标识符)来定义泛型类型参数。例如:

type Box<T> = {
value: T;
};

const boxNumber: Box<number> = { value: 42 };
const boxString: Box<string> = { value: 'hello' };

在这个例子中,Box<T> 是一个泛型类型,T 是类型参数。你可以根据需要传入不同的类型参数来创建不同类型的 Box

2. 多个类型参数

你可以在一个类型定义中使用多个类型参数:

type Pair<T, U> = {
first: T;
second: U;
};

const pair1: Pair<number, string> = { first: 42, second: 'hello' };
const pair2: Pair<string, boolean> = { first: 'world', second: true };

3. 泛型约束

你可以使用 extends 关键字来约束泛型参数,确保它们满足某些条件。例如,你可以约束泛型参数必须具有某个属性:

type HasId<T extends { id: number }> = T & { name: string };

const obj1: HasId<{ id: number; age: number }> = {
id: 1,
age: 30,
name: 'Alice'
};
// const obj2: HasId<{ age: number }> = { age: 30, name: 'Bob' }; // 错误:缺少 id 属性

在这个例子中,HasId<T> 要求 T 必须包含 id 属性。

4. 默认类型参数

你可以为泛型参数提供默认类型,这样在没有显式指定类型参数时会使用默认类型:

type Container<T = string> = {
value: T;
};

const container1: Container = { value: 'default' }; // 使用默认类型 string
const container2: Container<number> = { value: 42 }; // 显式指定类型 number

泛型函数

你也可以在函数中使用泛型,使得函数可以处理多种类型的参数:

function identity<T>(arg: T): T {
return arg;
}

const num = identity<number>(42);
const str = identity<string>('hello');

泛型接口

你还可以在接口中使用泛型:

interface Box<T> {
value: T;
}

const boxNumber: Box<number> = { value: 42 };
const boxString: Box<string> = { value: 'hello' };

泛型类

在类中使用泛型也很常见,特别是在实现泛型容器类时:

class Box<T> {
value: T;

constructor(value: T) {
this.value = value;
}

getValue(): T {
return this.value;
}
}

const boxNumber = new Box<number>(42);
const boxString = new Box<string>('hello');

console.log(boxNumber.getValue()); // 42
console.log(boxString.getValue()); // hello

总结

通过使用泛型,你可以创建更加灵活和可重用的类型定义。泛型允许你在定义类型、函数、接口和类时使用类型参数,从而根据不同的需求调整类型。