在 TypeScript 中调用函数类型的联合

Calling unions of function types in 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());

code at 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 语句?

只需注释 f 的 return 类型,编译器就会看到您正在 return 使用的每个函数都与该类型兼容:

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