即使参数满足每个函数的约束,函数联合也不可调用

时间:2017-01-16 02:49:56

标签: typescript

我正在尝试编译这个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 ]);

是否有一个构造允许我表达这一点,而不必编写一个ScaleContinuousNumericScaleTime都可分配的简单接口?

1 个答案:

答案 0 :(得分:2)

这是意外的行为,在TypeScript til 3.3之前的版本中已得到修复。 the changelog中还提到了TypeScript 3.3:

  

改善了调用联合类型的行为

     

在以前的TypeScript版本中,只有在具有相同参数列表的情况下,才能调用可调用类型的并集。

     

...

     

在TypeScript 3.3中,这不再是错误。