泛型

1. 泛型函数

定义一个 identity 函数

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

给 identity 函数添加了 类型变量T. T 会捕获用户传入的类型,(比如: number),之后 T 就代表这个类型了。

这个版本的 identity函数 叫做泛型函数,因为 T 可以是任意的类型。

泛型函数的两种调用方法:

1. 传入所有的参数,包括类型参数,其中类型参数用 <> 括起来
const output = identity<string>('123');
即明确指定 T 就是 string, 因此会限制 arg 必须为 string 类型。
因此下面的代码会报错:  
const output = identity<string>(123);  因此 123 不是 string 类型,所以会报错。


2. 可以不传类型参数,编译器自己查看 '123' 的类型,自动推算出 T 为 string
const output = identity('123');

2. 泛型变量

想象下以下代码,因为 return 的值必然是个字符串,而 T 不一定是 string, 所以会报错。

又或者:

又因为数组具有 .length 属性,因此可以像下面这样:

即我们可以把泛型变量T作为类型的一部分,实际类型 T[]T 构成,增加了灵活性。

3. 泛型类型

const myIdentity: <T>(arg: T) => T = identity 又会等同于 const myIdentity: { <T>(arg: T): T } = identity

因此我们可以定义一个泛型接口:

接受参数的泛型接口:

4. 泛型类

与泛型接口类似

类有静态部分和实例部分,泛型类只能用于实例部分的类型,类的静态属性不能使用这个泛型类型。

5. 泛型约束

首先以下代码会报错:

因此我们需要约束类型 T 必须要有 length 属性, 我们可以定义一个接口来描述约束条件,使用接口和extends关键字来实现约束:

此时,要调用 identity, 那么参数必须有 length 属性

5.1 泛型约束中使用类型参数

声明一个类型参数,被另一个类型参数所约束。

关于 keyof:

因此 K extends keyof T,则 K 必须是对象 T 的某个属性名

5.2 泛型中使用类类型

Last updated

Was this helpful?