TypeScript 中安全遍历对象的三种方法:for...in、Object.keys 与 Object.entries
本文详解在 TypeScript 中遍历对象的三种常见方式:for...in、Object.keys 和 Object.entries。针对 TypeScript 静态类型检查导致的类型错误,分别介绍了使用 keyof 类型断言、类型转换及解构赋值等解决方案,并探讨了运行时属性与静态类型差异的根本原因。
JavaScript
在探讨使用 TypeScript 遍历对象之前,我们先回顾 JavaScript 中的实现方式,例如 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 HANGZHOUTypeScript
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 返回的是字符串类型的键,而对象的属性值类型可能不同,因此无法直接将字符串键分配给 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 中的类型是开放式的。因此,keyof 可能会少于在运行时获得的所有属性。
这进一步解释了为什么 keys() 返回的是 string[] 而非 (keyof Person)[]。
总结
至此,关于如何在 TypeScript 中正确遍历对象的内容介绍完毕,更多相关 TypeScript 遍历对象内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
JS合并多个数组的三种方法:concat、spread与flat
2026-11-05 17:39:45
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36








