TypeScript/TS入门学习3

79 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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关键字来继承某个接口,是这个泛型显示的拥有了哪些必要属性,方便在函数中直接安全的被使用