Given is the function signature below:
function foo(): string[] | number[]
Why does TS plain about the follow function call of filter?
foo().filter((v) => true);
^^^^^^
Error
This expression is not callable. Each member of the union type '{ (predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; } | { ...; }' has signatures, but none of those signatures are patible with each other.
Of course I can cast it to []
, but what is the proper way here? The error message is very difficult to understand? How would one decipher this?
Example: Playground
Given is the function signature below:
function foo(): string[] | number[]
Why does TS plain about the follow function call of filter?
foo().filter((v) => true);
^^^^^^
Error
This expression is not callable. Each member of the union type '{ (predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; } | { ...; }' has signatures, but none of those signatures are patible with each other.
Of course I can cast it to []
, but what is the proper way here? The error message is very difficult to understand? How would one decipher this?
Example: Playground
Share Improve this question edited Apr 12, 2021 at 17:14 zixiCat 1,0591 gold badge7 silver badges18 bronze badges asked Apr 12, 2021 at 16:11 HelloWorldHelloWorld 1,8634 gold badges38 silver badges88 bronze badges 1-
The piler cannot figure out how to call a method which is a union of overloaded and generic methods, as per microsoft/TypeScript#36390. You could synthesize a type that represents what happens when you
filter()
a union of arrays, like this, but I don't know if you'd really want to use that instead of the relatively easy-to-write type assertion ("cast") as you said. I'm happy to write up an answer unless you think I'm missing the point of your question. Let me know. – jcalz Commented Apr 12, 2021 at 19:33
2 Answers
Reset to default 5function foo(): (number|string)[]
For same reason as here: Typescript: How to map over union array type?
Probably because the first argument of the .filter()
method is typed in TS to have the type of the items in the array. Since your function is basically "returning" .filter((v: number)): number[] | filter((v: string)): string[]
the two signatures are inpatible.