打字稿编译器无法调用类型缺少调用签名的表达式

Typescript Compiler Cannot invoke an expression whose type lacks a call signature

我正在使用数组(来自 JavaScript)和列表(来自 facebook 不可变库)。我创建了以下函数:

fooFunc(descriptors: List<Descriptor> | Array<Descriptor>) {
  let descriptor = descriptors.find(d => d.game == game);
}

编译器说:

Cannot invoke an expression whose type lacks a call signature.

两个对象都有一个具有相同签名的方法 find。

有什么想法吗?

我使用的是 TypeScript 版本:2.0.2

看来两者的签名不一样:

Array.find:

find(
    predicate: (value: T, index: number, obj: Array<T>) => boolean, 
    thisArg?: any
): T | undefined;

List.find:

find(
    predicate: (value?: V, key?: K, iter?: /*this*/Iterable<K, V>) => boolean,
    context?: any,
    notSetValue?: V
): V;

因为他们有不同的签名,所以他们的并集不会让你使用find方法。 例如:

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

那是因为 a.fn 的类型 (a: number) => void | (a: string) => void 是不可调用的。
与您的示例相同。

由于您只对值感兴趣,那么两个签名都适合您,因此您可以将其强制转换为其中之一:

let descriptor = (descriptors as Array<Descriptor>).find(d => d.game == game);

这样就可以了。
另一种选择是:

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);
}