我正在尝试编译这个Typescript片段:
function foo(v: string) { return 'foo'; }
function bar(v: string | number) { return 'bar'; }
const notCallable: typeof foo | typeof bar = function() {} as any;
// Fails type check, even though all the unioned functions accept string.
notCallable('a');
编译器将notCallable
的类型推断为((v: string) => string) | ((v: string | number) => string)
,看起来很好,但不被视为可调用:
无法调用类型缺少调用签名的表达式。输入'((v:string)=> string)| ((v:string | number)=> string)'没有兼容的呼叫签名。
请注意,如果参数列表匹配,即使返回类型不同,也可以正常工作。
function foo(v: string) { return 'foo'; }
function bar(v: string) { return 0; }
const callable: typeof foo | typeof bar = function() {} as any;
// Passes type check, presumably because the parameter lists match exactly (even though they have different return types).
callable('a');
这个例子是我最初在尝试描述"连续数字D3缩放函数"的概念时发现的简化案例,我试图将其定义为:
import { ScaleContinuousNumeric, ScaleTime } from 'd3-scale';
type ValidScale = ScaleContinuousNumeric<number, number> | ScaleTime<number, number>;
const s: ValidScale = function() {} as any;
// No good, the only valid overload for `domain` is the no-argument one, even though both interfaces have one that accepts a superset of `Array<number>`.
s.domain([ 0, 1 ]);
是否有一个构造允许我表达这一点,而不必编写一个ScaleContinuousNumeric
和ScaleTime
都可分配的简单接口?
答案 0 :(得分:2)
这是意外的行为,在TypeScript til 3.3之前的版本中已得到修复。 the changelog中还提到了TypeScript 3.3:
改善了调用联合类型的行为
在以前的TypeScript版本中,只有在具有相同参数列表的情况下,才能调用可调用类型的并集。
...
在TypeScript 3.3中,这不再是错误。