Function unification cannot even be called by parameters satisfying each function constraint

I am trying to compile this Typescript fragment:

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');

The compiler describes the type notCallableas ((v: string) => string) | ((v: string | number) => string)which looks normal but is not considered callable:

Cannot invoke an expression whose type does not have a call signature. Type '((v: string) => string) | ((v: string | number) => string) 'does not have compatible call signatures.

Note that if the parameter list matches, it works fine even if return types are different.

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');

This example is a simplified case that I initially discovered when trying to describe the concept of "continuous numeric functions of scale D3", which I tried to define as:

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 ?

+5
1

, TypeScript 3.3, . TypeScript 3.3:

TypeScript , .

...

TypeScript 3.3 .

+1

Source: https://habr.com/ru/post/1675816/


All Articles