【问题标题】:TypeScript union function returning literal compiler errorTypeScript 联合函数返回文字编译器错误
【发布时间】:2019-08-31 04:44:28
【问题描述】:

有人可以告诉我 TypeScript 在这些涉及返回值类型推断的场景中“在想什么”吗?我猜这与字面扩大有关,但我不清楚为什么其中一种情况会失败。

我有一个类型 (ContainingType),它有一个名为 funcOrVal (FunctionOrValue) 的成员,它又是第三个成员之间的联合类型 (Value) 和一个返回 Value 对象的函数。

type ContainingType =  {
    funcOrVal: FunctionOrValue;
};

type FunctionOrValue = Value | (() => Value);

type Value = "this" | "that" | number;

A.现在,如果我创建一个 ContainingType 的实例并直接为 funcOrVal 分配一个 Value,就没有问题了。

const worksWithValue: ContainingType = {
    funcOrVal: "that"
};

B.但是,将 funcOrVal 分配给返回与以前相同的 Value 的函数会产生错误。这似乎只在分配字符串文字选项之一时发生。

const breaksWithLiteral: ContainingType = {
    funcOrVal: () => {
        return "that";
    }
};

C.除了分配一个数字而不是一个字符串文字选项之外,做同样的事情就可以了。

const worksWithNumber: ContainingType = {
    funcOrVal: () => {
        return 123;
    }
};

D.我可以通过首先将 Value 分配给显式类型的变量来使示例 B 工作。

const worksWithExplicitType: ContainingType = {
    funcOrVal: () => {
        const value: Value = "that";
        return value;
    }
};

E.此外,如果我将 FunctionOrValue 重新定义为只允许函数,示例 B 也可以工作。

type Function = () => Value;

type ContainingTypeFunctionOnly =  {
    func: Function;
};

const worksWithFunctionOnly: ContainingTypeFunctionOnly = {
    func: () => {
        return "that";
    }
};

问题

funcOrVal 作为联合类型和返回值作为文字类型的组合会导致编译器停止正确推断函数的返回类型是什么情况?

编辑: 当试图找出我正在使用的确切 TypeScript 版本时(我为项目选择了“使用最新可用”),tsv -v 显示了我的TypeScript 版本为 3.1.2。由于 3.3 是项目菜单中的一个选项,因此我切换了它,从那时起 - 即使切换回“使用最新可用的” - 我也无法重现错误。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    这很奇怪,我无法重现该问题。我试过这段代码,它有效:

    type ContainingType =  {
      funcOrVal: FunctionOrValue;
    };
    
    type FunctionOrValue = Value | (() => Value);
    
    type Value = "this" | "that" | number;
    
    const breaksWithLiteral: ContainingType = {
      funcOrVal: () => {
        return "that";
      }
    };
    

    你能给我们你的 Typescript 版本和你的 tsconfig 吗?

    好吧,我猜函数返回类型被推断为string 而不是"that"。如果你的 Typescript >=3.4,你可以这样做:

      funcOrVal: () => {
        return "that" as const;
      }
    

    或者简单地说(我认为更好):

      funcOrVal: (): Value => {
        return "that";
      }
    

    但同样,我无法重现该问题...希望我有所帮助!

    【讨论】:

    • 这实际上有很大帮助 - 在试图找出我的 TS 版本时,我更改了项目设置,即使将其更改回来,错误也消失了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    相关资源
    最近更新 更多