Arrays Typescript编译器赢得';不允许调用两种数组类型的并集上的方法 请考虑以下功能: function getArray(): string[] | number[] { return []; }
长话短说,当我这样做:Arrays Typescript编译器赢得';不允许调用两种数组类型的并集上的方法 请考虑以下功能: function getArray(): string[] | number[] { return []; },arrays,typescript,types,Arrays,Typescript,Types,长话短说,当我这样做: getArray().forEach(item => console.log(item)); 编译器告诉我: TS2349无法调用类型缺少调用签名的表达式 为什么会这样?在我看来,forEach应该能够在这里被调用而不会出错,就编译器而言,可以肯定会返回一个数组。有趣的是,IntelliSense将一如既往地为该方法提供自动完成功能,但在执行自动完成建议后,错误消息将显示在输出中 这是一个bug,还是我遗漏了一些琐碎的东西 Edit:我可以使用各种解决方法
getArray().forEach(item => console.log(item));
编译器告诉我:
TS2349无法调用类型缺少调用签名的表达式
forEach
应该能够在这里被调用而不会出错,就编译器而言,可以肯定会返回一个数组。有趣的是,IntelliSense将一如既往地为该方法提供自动完成功能,但在执行自动完成建议后,错误消息将显示在输出中
这是一个bug,还是我遗漏了一些琐碎的东西
Edit:我可以使用各种解决方法,比如返回
Array
,或者使用重载,但我特别感兴趣的是为什么返回两种数组类型的并集不允许方法调用
可以肯定的是,该类型是一个数组,其元素类型为
string | number
一般来说,没有一种好的“安全”方法来处理联合类型的方法调用,其中方法具有不同的签名(当这些方法具有相同的签名时,TypeScript将允许方法调用),就好像只有一个方法一样
考虑这个例子:
class ValueHaver<T> {
value: T;
update(x: () => T) { this.value = x(); }
}
let x: ValueHaver<number> | ValueHaver<string> = /*...*/;
x.update(() => 42);
类估价师{
值:T;
更新(x:()=>T){this.value=x();}
}
设x:ValueHaver | ValueHaver=/*…*/;
x、 更新(()=>42);
此代码不正确。如果x
被证明是ValueHaver
,那么您将有一个数字
位于字符串
应该位于的位置
但是这个调用与数组|数组
的forEach
调用一样有效(假定一些假设的规则集)
您可能会说“嗯,您可以尝试为联合中的每种可能的
X
类型调用方法X.y
”。理论上这是可行的,但在实践中(尤其是在TypeScript2.0中),您可以很容易地得到包含几十个成分的联合类型。知道特定类型是否有效的唯一方法是再次对整个调用及其参数(因为上下文类型)进行类型检查,这将非常昂贵。由于技术原因,TS编译器通常无法做到这一点——一旦解析了给定表达式的类型,它就会被缓存。您不能对类型字符串[]数字[]
调用forEach
您可能需要的是:Array
:
或者,您可以强制转换到任何:
(getArray() as any[]).forEach(item => { /* item is any */ });
函数getArray():[string | number]{
也可以工作,原因相同。[string | number]
是一个长度为1的元组,它实际上没有清楚地传达函数的意图!
(getArray() as string[]).forEach(item => { /* item is a string */ });
(getArray() as any[]).forEach(item => { /* item is any */ });