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"
);