即使参数满足每个函数的约束,也不能调用函数的并集

stu*_*ffy 7 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');
Run Code Online (Sandbox Code Playgroud)

编译器推断notCallableas 的类型((v: string) => string) | ((v: string | number) => string),看起来不错,但不被视为可调用:

无法调用类型缺少调用签名的表达式。输入'(((v:string)=> string)| (((v:字符串|数字)=>字符串)'没有兼容的呼叫签名。

请注意,如果参数列表匹配,则即使返回类型不同,它也可以正常工作。

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');
Run Code Online (Sandbox Code Playgroud)

此示例是一个简化的案例,我最初是在尝试描述“连续数字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 ]);
Run Code Online (Sandbox Code Playgroud)

是否有一个结构,让我来表达这个,而无需编写一个简单的界面,这两个ScaleContinuousNumericScaleTime可分配给?

Dan*_*iel 3

这是 TypeScript 版本 3.3 之前出现的意外行为,该问题已得到修复。TypeScript 3.3 的变更日志中也提到了这一点:

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

在 TypeScript 的早期版本中,只有当可调用类型具有相同的参数列表时,才能调用它们的联合。

...

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