Skip to content

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
}

💻 playground


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
  // ...
}

💻 playground


ts
for (const kStr in obj) {
  const k = kStr as keyof typeof obj
  //    ^? const k: "one" | "two" | "three"
  const v = obj[k] // OK
}

💻 playground


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
  }
}

💻 playground


ts
const x = { a: 'a', b: 'b', c: 2, d: new Date() }
foo(x) // OK

💻 playground


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
  }
}

💻 playground


ts
function foo(abc: ABC) {
  for (const [k, v] of Object.entries(abc)) {
    //        ^? const k: string
    console.log(v)
    //          ^? const v: any
  }
}

💻 playground


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
  }
}

💻 playground


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
}

💻 playground

Released under the MIT License.