Home > Software design >  TS error on iterating through an array of objects
TS error on iterating through an array of objects

Time:11-10

I want to loop through an array of objects in js to find the element with a specific key.

It's worth noting that, the 'specific key' will exist in only one of the objects and no more. (it is also possible the 'key' will not exist in any of the objects)

For Example:

const arr: [
      { foo: number; fooo: number },
      { bar: number; barr: number },
      { baz: number; bazz: number }
    ] = [
      { foo: 100, fooo: 1 },
      { bar: 3, barr: 200 },
      { baz: 0, bazz: 0 },
    ];

I am using below code to find the object which has the wanted key:

const wantedObj = arr.find((el) => (typeof el.baz !== 'undefined'))

Since it is possible for the key to have a falsey value (ex: 0 ), I am checking (typeof el.baz !== 'undefined') condition.

But I get the TS error of

Property 'bazz' does not exist on type '{ foo: number; fooo: number; } | { bar: number; barr: number; } | { baz: number; bazz: number; }'.
Property 'bazz' does not exist on type '{ foo: number; fooo: number; }'.ts(2339)

Why is TS giving this error while I have obviously defined the type of arr? and how to fix it?

CodePudding user response:

Not every object in arr has a baz property. That's why the type of el inside the find looks like this:

{
    foo: number;
    fooo: number;
} | {
    bar: number;
    barr: number;
} | {
    baz: number;
    bazz: number;
}

Whenever you have a union of different object types, you can only access shared properties with the dot-notation.

We have to narrow the type of el first before accessing baz. The in operator let's us check an object for any property. Even those which are not defined in its type. The in operator also lets us narrow the union to those elements where the property exists.

const wantedObj = arr.find((el) => 
  "baz" in el && typeof el.baz !== "undefined"
);

Playground

  • Related