Typescript array find possibly undefind
If you're absolutely sure that you'll always get a match then you can tell TS so:
const getData = (query: "one" | "two") => (namedItems.find((item) => query === item.name) as Item).data;
Explanation
The reason you are experiencing this is the type signature for Array.prototype.find
:
find(predicate: (value: T, index: number, obj: T[]) => boolean, thisArg?: any): T | undefined;
As you can see, it always returns T | undefined
. This makes a lot of sense because a collection defined as Item[]
can contain an arbitrary number of items — including 0. In your case, the collection is complete, but on the type level it's no different than [{ name: "one", data: "some data one" }]
or even []
.
In order to access item.data
in a type-safe manner, TypeScript will require you to double check whether the result is indeed found.
const lookup = namedItems.find(item => item.name === 'one');
if (lookup === undefined) {
throw new TypeError('The value was promised to always be there!');
}
console.log(lookup.data);
Solution
Since this can become cumbersome in the long run, you may find it useful to create a helper function for this kind of scenarios.
function ensure<T>(argument: T | undefined | null, message: string = 'This value was promised to be there.'): T {
if (argument === undefined || argument === null) {
throw new TypeError(message);
}
return argument;
}
Usage:
const getData = (query: "one" | "two") =>
ensure(namedItems.find(item => query === item.name)).data