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