Item 60: Know How to Iterate Over Objects
要点
- Be aware that any objects your function receives as parameters might have additional keys.
- Use
Object.entries
to iterate over the keys and values of any object. - Use a ++for-in++ loop with an explicit type assertion to iterate objects when you know exactly what the keys will be.
- Consider
Map
as an alternative to objects since it's easier to iterate over. - 要注意函数接收的任何对象作为参数可能包含额外的键。
- 使用
Object.entries
来遍历任何对象的键和值。 - 当你确切知道对象的键时,使用
for-in
循环并进行显式的类型断言来遍历对象。 - 考虑使用
Map
作为对象的替代品,因为它更容易进行迭代。
正文
ts
const obj = {
one: 'uno',
two: 'dos',
three: 'tres',
}
for (const k in obj) {
const v = obj[k]
// ~~~~~~ Element implicitly has an 'any' type
// because type ... has no index signature
}
ts
const obj = { one: 'uno', two: 'dos', three: 'tres' }
// ^? const obj: {
// one: string;
// two: string;
// three: string;
// }
for (const k in obj) {
// ^? const k: string
// ...
}
ts
for (const kStr in obj) {
const k = kStr as keyof typeof obj
// ^? const k: "one" | "two" | "three"
const v = obj[k] // OK
}
ts
interface ABC {
a: string
b: string
c: number
}
function foo(abc: ABC) {
for (const k in abc) {
// ^? const k: string
const v = abc[k]
// ~~~~~~ Element implicitly has an 'any' type
// because type 'ABC' has no index signature
}
}
ts
const x = { a: 'a', b: 'b', c: 2, d: new Date() }
foo(x) // OK
ts
function foo(abc: ABC) {
for (const kStr in abc) {
let k = kStr as keyof ABC
// ^? let k: keyof ABC (equivalent to "a" | "b" | "c")
const v = abc[k]
// ^? const v: string | number
}
}
ts
function foo(abc: ABC) {
for (const [k, v] of Object.entries(abc)) {
// ^? const k: string
console.log(v)
// ^? const v: any
}
}
ts
function foo(abc: ABC) {
const keys = ['a', 'b', 'c'] as const
for (const k of keys) {
// ^? const k: "a" | "b" | "c"
const v = abc[k]
// ^? const v: string | number
}
}
ts
const m = new Map([
// ^? const m: Map<string, string>
['one', 'uno'],
['two', 'dos'],
['three', 'tres'],
])
for (const [k, v] of m.entries()) {
// ^? const k: string
console.log(v)
// ^? const v: string
}