【问题标题】:Possible to iterate over two union arrays with flow可以使用流迭代两个联合数组
【发布时间】:2018-12-19 04:13:00
【问题描述】:

我有一个函数foo,它接受两个数组的联合,它唯一做的就是循环遍历数组,但是这样我得到了流类型错误,数组中缺少一些属性。难道不能这样做吗?我根本没有使用任何属性。它们都是数组,所以 flow 应该知道它们是可迭代的。

A live example in the flow editor

type Handle = {|
  +articleId: string,
  +type: 'handle',
  +accessories: Array<string>,
  +positionInfo: string,
|};

type Leg = {|
  +articleId: string,
  +type: 'leg',
|};

type Entity = Handle | Leg;

function foo(entities: Array<Handle> | Array<Leg>) {
  entities.forEach(() => {})
}

【问题讨论】:

  • 检查属性是否可用。但是当你使用它时,它会遍历数组的每个实体,这会产生错误。
  • 但我根本没有使用任何属性?
  • 但 entity.forEach(() => {}) 尝试访问两个数组中的相同属性。
  • 看起来像一个错误..
  • 但它根本没有访问任何属性@UllasHunka 如果 Array 类型是一个接口,那么所有作为数组的东西都应该可以交互,对吧?

标签: javascript flowtype


【解决方案1】:

您可以键入包含Entity 对象的数组(例如Array&lt;Entity&gt;),您可以稍后对其进行细化。或者,您可以将输入键入为Array&lt;Handle | Leg&gt;,但由于您已经定义了Entity 类型,我们应该使用它。

(Try)

// I made these types writeable and non-exact since it
// doesn't seem to matter for the sake of this question.
// You can make them read-only and exact in your code if
// you want (and I personally would unless I had good
// reason not to).

type Handle = {
  type: 'handle',
  articleId: string,
  accessories: Array<string>,
  positionInfo: string,
}

type Leg = {
  type: 'leg',
  articleId: string,
}

type Entity = Handle | Leg;

function foo(entities: Array<Entity>) {
  entities.forEach(entity => {
    // At this point, flow knows that our `entity` variable
    // either contains a Handle or a Leg (from the above
    // definition of the `Entity` type.) We can use a
    // refinement to figure out which one it is:
    if (entity.type === 'leg') {
      const {type, articleId} = entity
      console.log("A leg", type, articleId) 
    } else if (entity.type === 'handle') {
      const {type, articleId, positionInfo} = entity
      console.log("A handle", type, articleId, positionInfo) 
    } else {
      // We can even assert that we covered all possible
      // cases by asserting that the `entity` value has
      // no remaining union cases and is therefore empty
      (entity: empty) 
    }
  })
}

const entitiesExample = [
  {articleId: 'blah', type: 'leg'},
  {articleId: 'toot', type: 'handle', accessories: [], positionInfo: 'bar'}
]

foo(entitiesExample)

旁注:如果我使用== 检查type 属性而不是上面的===,我注意到流在优化类型时遇到了麻烦。如果有人知道那里发生了什么,我很想知道,因为我的直觉是 == 应该可以正常工作。

【讨论】:

  • 听起来像是解决方法,但没有回答为什么不允许迭代 entities: Array&lt;Handle&gt; | Array&lt;Leg&gt;
  • @Aleksey,在运行 foreach 时,流不会将 Array&lt;Handle&gt; | Array&lt;Leg&gt; 视为等同于 Array&lt;Handle | Leg&gt;。也许应该。
  • 不,我认为它不应该被视为Array&lt;Handle | Leg&gt;,但它绝对应该是@​​987654335@
猜你喜欢
  • 2013-04-20
  • 2012-10-04
  • 2015-07-30
  • 2021-04-25
  • 2022-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-17
相关资源
最近更新 更多