1:为什么要用泛型
在模块化,组件化的今天,使用泛型主要是实现重用,使一个组件可以支持多种类型的数据,也许你可能会说我可以使用any呀,但一方面我们要有良好的代码规范,另一方面,如果我们使用any,则会失去编译器类型保护的作用。在项目中一般都提倡尽量少的使用any。那么为了实现重用就要用到泛型了。
2:泛型的使用
2.1在接口定义中使用
interface Indentities<V,M> {
value:V;
message:M
}
2.2在函数中的使用
function indentity(value:T,message:U):Indentities{
const indentities:Indentities ={
value,
message
};
return indentities;
}
indentity(1,'hello');
//上面的尖括号也可省略
2.3在定义类中使用(直接跟在类名后面)
// implements定义一个类并去实现接口
interface Indentities <U> {
value:U;
getIndentity:() => U
}
class IndentityClass<T> implements Indentities <T>{
value:T;
constructor(value:T) {
this.value = value
}
getIndentity():T {
return this.value;
}
}
const numberClass = new Indentity<number>(6);
const stringClass = new Indentity<string>('hello');
3:什么时候使用泛型
1:当函数,接口,类,处理多种数据类型的时候;
2:当函数,接口,类,在多个地方使用该数据类型的时候;
4:泛型约束
对类型变量接收的类型进行限制
例如
function indentity<T>(arg:T):T {
console.log(arg.length); //Error T doesn't have .length
return arg;
}
因为编译器不能确保所有的类型都有length,所以就会报错。
因此我们需要列出对T的约束条件,我们可以使用接口和extends关键字来实现。
如:
interface Lengthwise {
length:number;
}
function Indentity<T extends Lengthwise>(arg:T ):T {
console.log(arg.length);
return arg;
}
Indentity(3);//Error
Indentity({
length:3})
这时的泛型函数被定义了约束,不再适用于所有类型。