目录
class类中的泛型
泛型介绍
要在TS中实现一个函数fun,它的唯一参数可以是任何值,返回值也是传入参数的类型,我们应该怎么做呢?有人会脱口而出,用any类型的变量和返回值,但是这样就跳过了TS的类型检查,我们并不希望这样实现,于是我们给代码增加类型声明:
type idBoolean = (arg: boolean) => boolean;
type idNumber = (arg: number) => number;
type idString = (arg: string) => string;
...
但这样的方法也是不可行的,如果要有多种类型,我们就必须重复的编写相同逻辑的代码,这会给后期的维护带来特别大的隐匿。
泛型约束
为了解决上面的这些问题,我们使用泛型对上面的代码进行重构。和我们的定义不同,这里用了一个 类型 T,这个 T 是一个抽象类型,只有在调用的时候才确定它的值,这就不用我们复制粘贴无数份代码了。
function identity<T>(arg: T): T {
return arg;
}
其中 T
代表 Type,在定义泛型时通常用作第一个类型变量名称。但实际上 T
可以用任何有效名称代替。
其实并不是只能定义一个类型变量,我们可以引入希望定义的任何数量的类型变量。比如我们引入一个新的类型变量 N,用于扩展我们定义的 identity
函数:
function identity <T, U>(value: T, message: N) : T {
console.log(message);
return value;
}
console.log(identity<Number, string>(23, "Du"));
为了使代码更加简洁,我们可以省略函数调用时的类型显示声明,让编译器自动选择这些类型:
console.log(identity<Number, string>(23, "Du"));
//上下代码是等价的,下边的代码更加简洁
console.log(identity(23, "Du"));
泛型继承接口
我们还可以使用泛型去继承接口:
interface Person {
age: number;
}
functione Student<T extends Person>(stu: T): T {
console.log(stu.age);
return stu;
}
class类中的泛型
class MyClass<T>{
name:T,
constructor(name:T){
this.name = name;
}
}
const per1 = new MyClass<string>(name:"Du")
//上下两种实例化对象是等价的
const per2 = new MyClass(name:"Du")