开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
泛型约束
- 在ts中,我们需要严格的设置各种类型,我们使用泛型之后,将变的更加灵活,但是也存在一些问题,有些时候要明确告诉编译器我们的类型约束
- 我们需要对泛型进行约束来解决这些问题
下面代码编译不通过,因为无法识别泛型是什么类型
function getLength<T>(arr: T): T {
console.log(arr.length)
return arr.length;
}
getLength('实则棒')
解决方法1
,将参数的类型设置成Array,函数中的类型错误就不会再报,然后如果参数是一个Array,函数执行也没有问题了,但是字符串也是有length属性的,我们可以能也想通过这函数获取字符串的长度,传个字符串可以吗?肯定是不可以的,因为参数arr的类型为Array。
function getLength<T>(arr: Array<T>): number {
console.log(arr.length)
return arr.length;
}
getLength(['实则棒'])
解决方法2
这样虽然是解决了问题,但是代码实在不太优雅,太丑了。既然使用了泛型,就不该这么墨迹了。
function getLength<T>(arr: Array<T> | string): number {
console.log(arr.length)
return arr.length;
}
getLength(['实则棒'])
getLength('实则棒')
解决方案3 最优解
上面解决方案,要么解决不了问题,要么解决起来太难看,还是要正规方法解决问题,使用泛型约束,定义一个接口,里面有length属性,然后函数中的泛型必须继承于这个接口,也就是必须要有length属性的对象才能成为这个函数的参数,这样以来,函数里面就可以肆无忌惮的读取参数的length,编译器也就无理由报错了
interface ILength {
length: number
}
function getLength<T extends ILength>(arr: T): number {
console.log(arr.length)
return arr.length;
}
getLength(['实则棒'])
getLength('实则棒')
总结
泛型约束的使用是用extends关键字来继承某个接口,是这个泛型显示的拥有了哪些必要属性,方便在函数中直接安全的被使用