索引类型,key的约束
再for循环中我们经常遇到类似这种写法
const obj = {
a: 1,
b: 2,
c: 3
};
//遍历obj拿到指定key对应的val数组
function getObjVal(obj:any,keys:string[]) {
return keys.map(key => obj[key]);
}
console.log(getObjVal(obj, ["a", "b"]));
console.log(getObjVal(obj, ["d", "e"]));
当我们需要遍历一些对象的key值时,可能会有这种情况,但是这样写ts无法正确的限制你的keys数组是否都是属于obj的值。
使用ts不就是为了避免这种问题吗,再静态的时候就把错误提示出来,但是上面那段代码,我们consoe最终输出却是这样的。
[1,2]
[undefined,undefined]
为了避免出现undefined,我们需要利用泛型来约束第一个参数obj,然后通过keyof T
索引类型查询操作符来约束keys参数必须是T中存在的key。
改写
function getObjVal<T>(obj:T,keys:(keyof T)[]) {
return keys.map(key => obj[key]);
}
这样,当keys的值是不存在于obj的key时就会警告报错。但是需要注意keyof T
用括号包裹起来,不然无法正确的识别。
keyof T
获得的是联合泛型T的key值,大概示意如下:
"a" | "b" | "c" //字面量的联合属性
当然这种不太好看,我们可以利用泛型的继承特性,去除括号包裹
function getObjVal<T,K extends keyof T>(obj:T,keys:K[]) {
return keys.map(key => obj[key]);
}
当我们鼠标放在函数名上时,可以看到函数的返回值也有了更准确的类型约束
function getObjVal<T, K extends keyof T>(obj: T, keys: K[]): T[K][]
T[K][]
成了返回类型约束,返回一个数组,数组的值必须是泛型T对应的K泛型得到的值。
分类:
TypeScript
标签:
TypeScript索引类型keyof T泛型约束
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据