flowtype - 应该如何构建不相交的联合包装器才能使细化发挥作用?

标签 flowtype

On the Flowtype "Try" site

// @flow

type One = {type: "One"};
type Two = {type: "Two"};
type Node = One | Two;


class Foo<N: Node> {
  node: N;

  constructor(n: N) {
    this.node = n;
  }
}

const fooNode: Foo<Node> = new Foo({type: "One"});
if (fooNode.node.type === "One") {
  const fooOne: Foo<One> = fooNode;
}

如果我理解正确的话,if 类型检查不足以细化类型,因为不能保证类型是常量。

由于我想避免出现 X/Y 问题,因此我目前正在使用的用例是使用 .find 方法从给定节点进行搜索,该方法将返回精炼类型,例如使用

  parent(): Foo<N> | null {
    // ...
    return null;
  }

  find<U: Node>(callback: (foo: Foo<N>) => Foo<U> | null): Foo<U> | null {
    let p = this;
    do {
      const result = callback(p);
      if (result) return result;

      p = p.parent();
    } while (p);

    return null;
  }

const f: Foo<Node> = new Foo({type: "One"});

const result: Foo<Two>|null = f.find((p) => p.node.type === "Two" ? p : null);

这将允许我在搜索时返回精炼类型。

最佳答案

问题出在这一行的类型注释上:

const fooNode: Foo<Node> = new Foo({type: "One"});

通过明确使用 Foo<Node>你正在阻止细化的发生。您可以使用Foo<*>使推理正确进行。

这是一个例子: https://flowtype.org/try/#0PTAEAEDMBsHsHcBQiAuBPADgU1AeQHY4C8oA3qOtgFygBEBWtoAvgNyqY4Aq8soJ5Slhq0esJmw7ZQAOVgATYnkKgAPqDHtEAY2gBDAM4HQAMViwAPDJpzFAPjKJQofAuGytz7bHwGUAJwBXbRRYfwAKfBsASkdnZxQACwBLAwA6V0V+F3ZnZkR85G9fFFBIc1t3M0sAKgcSQnhTc3DSIREGWmZo9nDy2EqaaosGOx7EPoq3IfMLMTHWUBBQLH9-MKA

关于flowtype - 应该如何构建不相交的联合包装器才能使细化发挥作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41433907/

相关文章:

flowtype - Flow - 使用全局类型属性类型输入变量

javascript - 我如何注释我想要任何类型作为输入,但与 Flow 的输出类型相同?

javascript - 调用 `this.setState()` 会中断对 componentWillReceiveProps 中的 prop 进行流类型检查

javascript - 如何声明一组匹配文件的导出类型?

javascript - 原语的 Flowtype 标称类型

node.js - babel 未剥离流程的类型提示

flowtype - 无法将对象文字分配给 `...`,因为对象文字 [1] 中缺少属性 `...` 但存在于 `...`

flowtype - 如何在 Flow 接口(interface)声明中声明模块的根导出?

javascript - 流型。创建实现带有可选字段的接口(interface)的类的实例

javascript - 意外的流类型错误,可能为空对象