这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战
泛型约束
我们来看一个例子:
function echoWithArr<T>(arg:T):T{
console.log(arg.length)
return arg
报错信息:
这是因为在我们使用泛型函数内部变量的时候由于事先不知道他是哪种类型,所以我们不能随意的操纵他的属性或者方法.相比于操作any所有类型,我们想要限制函数去处理任意带有
.length属性的所有类型。 只要传入的类型有这个属性,我们就允许,就是说至少包含这一属性。 为此,我们需要列出对于T的约束要求。
function echoWithArr<T>(arg:T[]):T[]{
console.log(arg.length)
return arg
}
const arrs = echoWithArr([1,2,3])
这个时候我们可以看到arrs的类型:
这个解决方法不是最完美的,如果我们传入string类型的它依旧会报错
function echoWithArr<T>(arg:T[]):T[]{
console.log(arg.length)
return arg
}
const arrs = echoWithArr("1,2,3")
报错信息:
这个时候我们定义一个接口来描述约束条件。 创建一个包含.length属性的接口,使用这个接口和extends关键字还实现约束:
interface IWithLength{
length:number
}
function echoWithArr<T extends IWithLength>(arg:T):T{
console.log(arg.length)
return arg
}
const str = echoWithArr('123')
const obj = echoWithArr({length:10})
const arr = echoWithArr([1,2,3])
这个时候我们的数据类型就是正确的了
如果我们传入错误的值那么还是会报错:
interface IWithLength{
length:number
}
function echoWithArr<T extends IWithLength>(arg:T):T{
console.log(arg.length)
return arg
}
echoWithArr(12)
报错信息:
总结
这里我们主要用到extends关键,使我们的泛型得到了约束,只有满足特定条件才能正常使用,而不是想传什么类型的值就传什么类型的值。