可以使用流迭代两个联合数组

时间:2018-07-11 07:55:09

标签: javascript flowtype

我有一个函数foo,它接受​​两个数组的并集,并且唯一要做的就是在数组上循环,但是这样做会导致flowtype错误,即数组中缺少某些属性。这是不可能的吗?我根本没有使用任何属性。它们都是数组,因此流应该知道它们是可迭代的。

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(() => {})
}

1 个答案:

答案 0 :(得分:2)

您可以将数组键入为包含Entity个对象(例如Array<Entity>),然后可以对其进行优化。另外,您可以将输入键入为Array<Handle | Leg>,但是由于您已经定义了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上进行了===检查,流程就无法细化类型。如果有人知道那里发生了什么,我很想知道,因为我的直觉是==应该可以正常工作。