Reputation: 18483
This will never fail to return an array of strings:
(arr: (string | undefined)[]): string[] => arr.filter(item => item !== undefined);
But TypeScript does not accept to compile this because it doesn't infer that the filter predicate will return true
if and only item
is a string. Explicitly typing the predicate doesn't seem to help either:
const predicate = (item: string | undefined): item is string => item !== undefined;
(arr: (string | undefined)[]): string[] => arr.filter(item => predicate(item));
This works but is much wordier (and if I'm not mistaken, much slower):
(arr: (string | undefined)[]): string[] => {
const ret: string[] = [];
for (const item of arr) {
if (item !== undefined) {
ret.push(item);
}
}
return ret;
}
Is there an experimental flag I can enable in my tsconfig.json
that'll enable TypeScript to make type inferences based on the .filer
predicate?
Upvotes: 0
Views: 342
Reputation: 33701
You are using an anonymous inline function instead of the predicate:
const predicate = (item: string | undefined): item is string => item !== undefined;
(arr: (string | undefined)[]): string[] => arr.filter(item => predicate(item)); // error
(arr: (string | undefined)[]): string[] => arr.filter(predicate); // ok
// inline predicate
(arr: (string | undefined)[]): string[] => arr.filter((item): item is string => item !== undefined);
Upvotes: 3