请考虑以下函数:
function getArray(): string[] | number[] {
return [];
}
长话短说,当我这样做时:
getArray().forEach(item => console.log(item));
编译器给了我这个:
TS2349 Cannot invoke expression whose type lacks a call signature.
为什么会发生这种情况?我是这样看的,forEach
应该能够在此处调用而不会出现错误,就编译器而言,肯定会返回一个数组。有趣的是,IntelliSense 将像往常一样为此方法提供自动完成功能,但在使用自动完成建议后,错误消息将显示在输出中。
这是一个错误,还是我在这里遗漏了一些微不足道的东西?
编辑:我可以使用各种解决方法,例如返回 Array<string | number>
相反,或使用重载,但我特别感兴趣的是为什么返回两个数组类型的联合不允许方法调用。
可以确定类型是数组,元素类型为 string | number
.
最佳答案
一般来说,没有一个好的“安全”方法来处理具有不同签名的联合类型的方法调用(当这些方法具有相同的签名时,TypeScript 将允许方法调用),就好像有只有一种方法。
考虑这个例子:
class ValueHaver<T> {
value: T;
update(x: () => T) { this.value = x(); }
}
let x: ValueHaver<number> | ValueHaver<string> = /*...*/;
x.update(() => 42);
此代码不正确。如果x
原来是ValueHaver<string>
,那么你就会有一个 number
坐在哪里string
应该是。
但是这个调用与 forEach
一样有效(假设有一些假设的规则集)调用Array<number> | Array<string>
.
您可能会说“好吧,您可以尝试为联合中 X.y
的每种可能类型调用方法 X
”。从理论上讲,这可以工作,但在实践中(尤其是在 TypeScript 2.0 中),您可以轻松获得具有数十个成分的联合类型。 知道特定类型是否有效的唯一方法是重新检查整个调用、及其参数(因为上下文类型),这将是令人望而却步的昂贵的。由于技术原因,TS 编译器通常无法做到这一点——一旦给定表达式的类型被解析,它就会被缓存。
关于arrays - Typescript 编译器不允许调用两个数组类型联合上的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39168974/