如何在TypeScript中正确的遍历一个对象
JavaScript
在讲解用 Ts 遍历一个对象之前, 我们先说说 在 Js 中怎么实现, for...in、Object.keys, 一个简单的例子:
// for...in
const obj = {
name: 'itsuki',
address: 'hangzhou',
};
for (const key in obj) {
console.log(key, obj[key].toUpperCase());
}
// Object.keys
Object.keys(obj).forEach(key => {
console.log(key, obj[key].toUpperCase());
});
// 输出
// name ITSUKI
// address HANGZHOU
TypeScript
for...in
但是在 TypeScript 中, 如果你直接这么用的话, 发现会报错.
type Person = {
name: string;
address: string;
};
const obj: Person = {
name: 'itsuki',
address: 'hangzhou',
};
function print(obj: Person) {
for (const key in obj) {
// ❌
// key:string 不能分配给 { name:string; age:number }类型
console.log(key, obj[key].toUpperCase());
}
}
print(obj)
我们知道for...in、Object.keys拿到的是对象的 key, 而在对象中所有的 key 都是字符串, 所以它无法分配给Person的name、address.
但是我们可以keyof来解决这个问题.
function print(obj:Person){
let key: keyof Person;
for (key in obj) {
// ✅
console.log(key, obj[key].toUpperCase());
}
}
Object.keys
在使用Object.keys时, 我们可以使用as运算符来解决.
function print(obj: Person) {
Object.keys(obj).forEach((k) => {
// ✅
console.log(k, obj[k as keyof Person].toUpperCase());
});
}
我们可以把这个抽离出一个函数:
function getKeys<T>(obj: T) {
return Object.keys(obj) as Array<keyof T>;
}
getKeys(obj); // (keyof Person)[]
Object.entries
我们也可以使用Object.entries()来遍历对象.
Object.entries(obj).forEach(([k, v]) => {
console.log(k, v);
});
思考
以下是我自己的思考, 如有错误, 请指正
我想Object.keys()返回的是一个string[], 是因为它是在运行时确定的, 我们知道TypeScript做的只是静态类型的检查, 即使我们使用keyof Person返回了 name | address, 但是我们不能肯定在运行时它就是这两个字段.
比如说:
const obj2 = {
name: 'itsuki',
address: 'hangzhou',
age: 20,
};
print(obj2)
// 编译时: ✅, 因为它有name、address属性
// 运行时: ❌, 因为age字段是number, 没有toUpperCase方法
然后我在 Github issue 里面找到这一句话:
TS 中的类型是开放式的。因此, keysof 可能会少于在运行时获得的所有属性。
它更要我明白了, 为什么keys()返回的是一个string[], 而不是一个(keyof Person)[].
总结
到此这篇关于如何在TypeScript中正确的遍历一个对象的文章就介绍到这了,更多相关Ts遍历对象内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341