再for循环中我们经常遇到类似这种写法

typescript
复制代码
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最终输出却是这样的。

javascript
复制代码
[1,2] [undefined,undefined]

为了避免出现undefined,我们需要利用泛型来约束第一个参数obj,然后通过keyof T索引类型查询操作符来约束keys参数必须是T中存在的key。

改写

typescript
复制代码
function getObjVal<T>(obj:T,keys:(keyof T)[]) { return keys.map(key => obj[key]); }

这样,当keys的值是不存在于obj的key时就会警告报错。但是需要注意keyof T用括号包裹起来,不然无法正确的识别。

keyof T获得的是联合泛型T的key值,大概示意如下:

typescript
复制代码
"a" | "b" | "c" //字面量的联合属性

当然这种不太好看,我们可以利用泛型的继承特性,去除括号包裹

typescript
复制代码
function getObjVal<T,K extends keyof T>(obj:T,keys:K[]) { return keys.map(key => obj[key]); }

当我们鼠标放在函数名上时,可以看到函数的返回值也有了更准确的类型约束

javascript
复制代码
function getObjVal<T, K extends keyof T>(obj: T, keys: K[]): T[K][]

T[K][]成了返回类型约束,返回一个数组,数组的值必须是泛型T对应的K泛型得到的值。

分类: TypeScript 标签: TypeScript索引类型keyof T泛型约束

评论

暂无评论数据

暂无评论数据

目录