【问题标题】:Flow type distinguish between subtype union流类型区分子类型并集
【发布时间】:2018-07-03 23:49:53
【问题描述】:

我有这个扩展子类型的联合示例:

type TypeA = {|
    type: "a",
    value: number,
|};

type TypeB = {|
    type: "b",
    value: Array<number>,
|};

type SuperType =
    | TypeA & {|
        color: string,
    |}
    | TypeB;

function test(val: SuperType): void {
    if (val.type === "b") {
        // Flow should probably know that val.value is an array here
        console.log(val.value.length);
    }
}

(live flow.org/try link here)

但是,最后,当我尝试利用 Disjoint Unions with exact types 时,它失败了:

20:         console.log(val.value.length);
                                 ^ Cannot get `val.value.length` because property `length` is missing in `Number` [1].
References:
3:     value: number,
              ^ [1]

我不知道 Flowtype 是不支持这个还是我做错了什么。这发生在 Flow 0.66 上。请注意,如果我删除 {| color: string |} 位,这将有效。

【问题讨论】:

  • 你不能把color: string,放在TypeA里面吗?
  • 我不能(这是一个更复杂类型的最小示例,我真的不能),但与此同时,我设法使用...(扩展运算符)完成了这项工作而不是&amp;(交叉点)。不知道为什么它适用于传播,我认为这两个运算符是等价的。

标签: javascript flowtype


【解决方案1】:

SuperType 中,使用展开运算符... 而不是交集运算符&amp;

type TypeA = {|
    type: "a",
    value: number,
|};

type TypeB = {|
    type: "b",
    value: Array<number>,
|};

type SuperType =
    | {|
        ...TypeA,
        color: string,
    |}
    | TypeB;

function test(val: SuperType): void {
    if (val.type === "b") {
        // Flow should probably know that val.value is an array here
        console.log(val.value.length);
    }
}

Live demo on Try Flow

【讨论】:

  • &amp; intersection 不起作用的原因是TypeA &amp; {| color: string |} 中的&amp; 没有修改TypeA,而只是增加了一个额外的约束:该值必须是TypeA{| color: string |} 同时。这当然是不可能的:对象不能只包含color,同时也只能包含typevalue... 在对象类型中传播,另一方面,根据需要创建一个新的合并类型。
猜你喜欢
  • 2019-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-29
相关资源
最近更新 更多