【问题标题】:Cannot return object literal because null or undefined - Flow无法返回对象文字,因为 null 或未定义 - 流
【发布时间】:2019-03-14 18:38:29
【问题描述】:

将 mayBe 类型与对象文字的可选道具混合

 type Response = {
        data?: string;
    }

 function length(): ?string {
      return undefined;
 }

 function test(): Response {
    const data = length()
    return {
        data
    }
 }

12:         data        ^ Cannot return object literal because null or undefined [1] is incompatible with string [2] in property `data`.
References:
5: function length(): ?string {
                      ^ [1]
2:     data?: string;
              ^ [2]

Test Flow

遵循MayBe types 和Object Types 的流程文档 我不知道为什么会出现错误,有没有办法解决这个问题?

【问题讨论】:

    标签: flowtype flow-typed


    【解决方案1】:

    也许类型和可选对象属性在流中并不完全相同,并且并不总是兼容的。

    首先让我们看一下Maybe Types 的文档链接:

    也许类型接受提供的类型以及null 或undefined。所以?number 表示number、null 或undefined。

    所以?number 基本上是number | null | undefined。

    现在让我们看看您的对象类型链接from the docs:

    除了它们的设置值类型之外,这些可选属性可以是void 或完全省略。但是,它们不能是null。

    所以如果我们这样做type Response { data?: string },那么response.data基本上是string | void。请注意,void 是与 null 完全不同的类型。

    所以现在让我们分解你的例子:

    type Response = {
      data?: string; // void | string
    }
    
    function length(): ?string { // void | string | null
      return undefined;
    }
    
    function test(): Response {
      const data = length()
      // at this point, as far as flow knows, `data` can be `void`, `string`, or
      // `null`, and we're trying to set it as the `data` property on our
      // `Response` type which expects a `void` or a `string`, and does not
      // expect a `null`.
      return {
        data
      }
    }
    

    所以基本上,Response.data 期待void | string,而您正试图用void | string | null 设置它。类型必须在某处更改才能成功完成操作。有多种可能的方法:

    Option one,将 length 返回值更改为更具体。可能是最简单的:

    function length(): void | string {
      return undefined;
    }
    

    我们已经消除了data 成为null 的可能性,因此不再出现类型错误。

    Option two,使 Response.data 成为可能的类型

    如果他们都是可能的类型,那么问题就消失了。最小可能的变化是这个:

    type Response = {
        data?: string | null;
    }
    

    我们刚刚添加了Response.data 成为null 的可能性。现在它可以接受length的返回类型,类型匹配,没有错误。但这有点令人困惑,将null 与可选属性结合起来。我们可以这样做:

    type Response = {
        data: ?string,
    }
    

    Option three,细化类型:

    function test(): Response {
      const data = length()
      // at this point response.data is `void`
      const response = {};
      if (data) {
        // data is now a `number`, not `number | void | null`
        response.data = data;
      }
      // response.data is now `number | void` (not `null`)
    
      return response
    }
    

    决定使用这些选项中的哪一个几乎完全取决于针对当前问题的最佳 API,还可能是关于如何处理可选类型与一般类型的风格选择。

    【讨论】:

    • 这么好的答案,谢谢你帮我解决这个问题!
    • Hey Lyle 做 type Response = { data? = ?string} 也是解决此问题的一个选项?
    • 是的,这也是一种选择,但我不会在几乎所有情况下都推荐它。您应该考虑一下这对于围绕您的 API 进行的通信意味着什么。通过使用data?: ?string,您的意思是“data 属性在对象上是可选的,其值可以是string、undefined 或null。”用户真的需要那么多选项吗?还是只是令人困惑?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    • 2021-01-23
    • 1970-01-01
    • 2020-11-04
    • 2023-02-21
    • 2014-09-22
    相关资源
    最近更新 更多