Reputation: 7490
I'm using Array (from JavaScript) and List (from facebook immutable library). I create the following function:
fooFunc(descriptors: List<Descriptor> | Array<Descriptor>) {
let descriptor = descriptors.find(d => d.game == game);
}
The compiler says:
Cannot invoke an expression whose type lacks a call signature.
Both objects have a method find with the same signature.
Any ideas?
I'm using TypeScript version: 2.0.2
Upvotes: 0
Views: 1270
Reputation: 164147
It looks like the signatures of the two are different:
find(
predicate: (value: T, index: number, obj: Array<T>) => boolean,
thisArg?: any
): T | undefined;
find(
predicate: (value?: V, key?: K, iter?: /*this*/Iterable<K, V>) => boolean,
context?: any,
notSetValue?: V
): V;
Because they have different signatures, then the union of them won't let you use the find method. For example:
interface A {
fn(a: number): void;
}
interface B {
fn(a: string): void;
}
type both = A | B;
let a: both;
a.fn(3); // error: Cannot invoke an expressions whose type lacks a call signature
That's because a.fn
is of type (a: number) => void | (a: string) => void
which is not callable.
The same as with your example.
Since you are only interested in the values then both signatures can work for you, so you can just cast it to one of them:
let descriptor = (descriptors as Array<Descriptor>).find(d => d.game == game);
And that will work just fine.
Another option is to do this:
type MyArrayType<T> = (Immutable.List<T> | Array<T>) & {
find(predicate: (value: T) => boolean): T;
}
function fooFunc(descriptors: MyArrayType<Descriptor>) {
let descriptor = descriptors.find(d => d.game == game);
}
Upvotes: 1