泛型
泛型是指在定义函数,接口,或者类的时候,不预先指定具体的类型,而是在使用的时候在指定类型的一种特性
简单的例子
首先,我们来实现一个函数 createArray,它可以创建一个指定长度的数组,同时将每一项都填充一个默认值
function createArray(length: number, value: any): Array<any> {
let result = []
for (let i = 0; i < length; i++) {
result[i] = value
}
return result
}
createArray(3, 'x') // ['x', 'x', 'x']
上面代码不会报错,但是不能确定返回值的类型。这个时候就需要泛型了
function createArray<T>(length: number, value: T): Array<T> {
let result: T[] = []
for (let i = 0; i < length; i++) {
result[i] = value
}
return result
}
createArray < string > (3, 'x') // ['x', 'x', 'x']
上例中,我们在函数名后面添加了
多个类型参数
定义泛型的时候,可以一次定义多个类型的参数
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]]
}
swap([7, 'seven']) // ['seven', 7]
泛型约束
- 在函数内部使用泛型变量的时候,由于不知道他是那种类型,所以不能随意操作他的属性或者方法
function loggingIdentity<T>(arg: T): T {
console.log(arg.length)
return arg
}
// index.ts(2,19): error TS2339: Property 'length' does not exist on type 'T'.
利用 extends 继承
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
这样就能使用 length 属性了
泛型参数的默认类型
function createArray<T = string>(length: number, value: T): Array<T> {
let result: T[] = []
for (let i = 0; i < length; i++) {
result[i] = value
}
return result
}