【问题标题】:Flow: shape types and additional optional fields流:形状类型和其他可选字段
【发布时间】:2019-10-20 02:37:18
【问题描述】:

我经常发现自己需要做以下事情,而 Flow 让它变得非常困难:

/* @flow */

type Foo = {
  +foo?: number,
}

type FooBar = {
  +foo?: number,
  +bar?: number,
}

const foo: Foo = {foo: 2}

function process(arg: $ReadOnly<FooBar>) {
}

process(foo)

有什么好的方法吗?我收到以下错误:

17: process(foo)
            ^ Cannot call `process` with `foo` bound to `arg` because property `bar` is missing in `Foo` [1] but exists in `FooBar` [2].
References:
12: const foo: Foo = {foo: 2}
               ^ [1]
14: function process(arg: $ReadOnly<FooBar>) {
                                    ^ [2]

【问题讨论】:

    标签: flowtype structural-typing


    【解决方案1】:

    Flow 默认对象类型不精确;这意味着,尽管Foo 仅被声明为显式具有number 类型的单个(可选)属性foo,但Foo 类型的变量理论上可以具有其他属性。例如,Foo 类型的变量可以具有属性bar。而且,由于bar 没有在Foo 中输入,bar 的类型不受限制(即,不一定是number)。因此,如果您要与 process 中的 arg.bar 进行交互,并且 Flow 允许 arg 的类型为 Foo,则不能保证您与 number 进行交互。因此,Flow 抱怨。

    解决此问题的一种方法是使用精确的对象类型。如果 Flow 知道Foo 类型的变量永远不会有bar 属性,那么它可以安全地传递给process。因此,您可以将Foo 输入为:

    type Foo = {|
      +foo?: number,
    |};
    

    Try Flow

    (注意:$ReadOnly 实用程序类型对于Foo 的上述定义和FooBar 的原始定义不是必需的,因为bar 是不可写的。当然,保留$ReadOnly 很好.)

    【讨论】:

    • 啊对,我总是忘记这个。你知道 TypeScript 是否对形状类型同样严格吗?我还没有遇到过 Flow 对形状类型的严格要求真的值得麻烦的情况。
    • Flow will be making objects exact by default 所以你很快就不用担心这个了。不确定 TypeScript。
    猜你喜欢
    • 2021-09-21
    • 2016-09-07
    • 2022-01-14
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多