出乎意料的是,当我尝试在union类型的变量上调用方法时,我遇到了编译器错误。我已经隔离了这个问题,请参阅下面的代码。我想知道是什么阻止了编译器理解baz
应该是string
。是不是在编译器中没有实现(但是?)的某种边缘情况?或者这个代码是否有一些根本原因无效?
TypeScript版本:2.0.6
错误是:Cannot invoke an expression whose type lacks a call signature.
declare class A {
foo(arg: number[] | number): string;
}
declare class B {
foo(arg: number[]): string;
}
declare let bar: A | B;
let baz = bar.foo([3000]);
如果我在类A
中使用方法重载而不是联合类型,它就会开始工作。但是,我的问题是真正的A
和B
是在相对难以改变的第三方类型定义中定义的。
答案 0 :(得分:2)
您可能希望bar.foo
的类型为:
(arg: number[] | number) => string;
但实际上是这样的:
((arr: number | number[]) => string) | ((arr: number[]) => string)
这种类型确实无法调用。
如果您将B
更改为:
declare class B {
foo(arr: number[] | number): string;
}
然后错误就消失了(你可以明显改变A.foo
以匹配B
)。
类型:
((arr: number | number[]) => string) | ((arr: number[]) => string)
不可调用,因为编译器没有引用应该调用哪些函数
如果它能够引用它,那么它将以(arg: number[] | number) => string
类型开头。
当你执行此操作时它起作用的原因:
declare class A {
foo(arg: number): string;
foo(arg: number[]): string;
}
现在,A | B
类型有一个共同的方法:foo(arg: number[]): string
因此,bar.foo
的类型为(arr: number[]) => string
,并且之前没有冲突。