一、泛型
在使用ts封装一个函数时,由于入参是不固定的,必然参数类型也无法固定,这时就要用到泛型来定义参数类型。泛型可以理解为宽泛的类型,通常用于类和函数。
例1. 类中使用泛型
class Person<T>{
private name: T;
constructor(value: T) {
this.name = value;
}
}
const p = new Person<string>('Dalon')
例2. 函数中使用泛型
function identity<T>(data: T): T {
console.log(data)
return data;
}
const id1 = identity<string>('hey boy!');
const id2 = identity<number>(123456);
例3. 接口中使用泛型
interface Person<T1=string, T2=number> {
name: T1
age: T2
}
const dalon:Person = {
name: 'dalon',
age: 18
}
const tom:Person<string, string> = {
name: 'Tom',
age: '18'
}
例3中的T1和T2泛型添加了默认类型,类似于函数的默认参数。
二、泛型约束
泛型约束即是对泛型的类型进行约束控制,如限制为object类型或指定接口类型。当在函数里使用泛型参数的属性或者方法时,就需要对泛型进行约束。
例1. 通过接口约束
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // 如果没有Lengthwise泛型约束,会报错Error: T doesn't have .length
return arg;
}
例2. object约束
function getKeys<T extends object>(data:T) :string[] {
const keys:Array<string> = Object.keys(data)
return keys
}
上面例2的getKeys方法获取一个对象的所有属性名, 由于Object.keys是object的原型方法,所以要求data也必须是一个object类型。
(完)
参考文献: