Вызов объединений типов функций в TypeScript

В TypeScript 3.0.3 следующий код выдаст ошибку времени компиляции:

function f() {
    if (true) {
        return (x: {left:String}) => x.left;
    } else {
        return (x: {right:String}) => x.right;
    }
}

class C {
    left: String = "";
    right: String = "";
}

f()(new C());

код на typescriptlang.org

Я ожидал, что тип f будет function f(): {left:String; right:String} => String или эквивалентным (например, Scala typechecker сообщает о таком типе).

Однако я получил следующую ошибку типа:

./leftright.ts:17:1 - error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((x: { left: String; }) => String) | 
((x: { right: String; }) => String)' has no compatible call signatures.

17 f()(new C());

Кажется, что объединения типов функций не могут быть вызваны напрямую, несмотря на то, что мы можем ссылаться на поле в объединении типов объектов.

Есть ли способ изменить f() на вызываемый, сохранив внутри него if-оператор?


person Keigo Imai    schedule 03.09.2018    source источник
comment
Соответствующая проблема GitHub: github.com/Microsoft/TypeScript/issues/7294   -  person jcalz    schedule 03.09.2018


Ответы (1)


Просто аннотируйте возвращаемый тип f, и компилятор увидит, что каждая из возвращаемых вами функций совместима с этим типом:

function f(): (x: { left: String, right: String }) => String {
    if (true) {
        return (x: {left:String}) => x.left;
    } else {
        return (x: {right:String}) => x.right;
    }
}
person Matt McCutchen    schedule 03.09.2018