0

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

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

编译器说:

无法调用其类型缺少调用签名的表达式。

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

有任何想法吗?

我正在使用 TypeScript 版本:2.0.2

4

1 回答 1

1

看起来两者的签名不同:

Array.find

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;

因为它们有不同的签名,所以它们的并集不会让你使用 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.fnis 的类型(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);
}
于 2016-10-06T13:45:13.070 回答