I often use code like in example below and was wondering if there is some smart way to type the find
results without having to do explicit type assertion.
type Foo = { type: "Foo" };
type Goo = { type: "Goo" };
type Union = Foo | Goo;
const arr: Union[] = [];
const foo = arr.find(a => a.type === "Foo") as Foo;
If the as Foo
type assertion is left out, the result is of type Union
even though it can only return type Foo
.
What's the cleanest way of fixing the type of find
to return the narrowed type in examples like these?
Edit: This problem could be also applicable to filter
and other similar methods.
Edit2: Suggested similar question's accepted answer (Way to tell TypeScript compiler Array.prototype.filter removes certain types from an array?) shows that by using type guard in the predicate for find/filter
the return value can be narrowed down.
How should this type guard function look to narrow down any discriminated union if e.g. the distinguishing string literal is always under type
key?
arr.find(isTypeFromUnion("Foo"))
. – Flamingfind
as type guard like this:const maybeFoo = arr.find((a): a is Foo => a.type === "Foo"); // Foo | undefined
. TS – Aquacadeas Foo
toa is Foo
which means I would still need to explicitly write the type – Flaming