流程细化不会“向上”传播吗?

时间:2017-01-12 03:16:28

标签: flowtype

我很惊讶地看到this example没有进行类型检查:

/* @flow */

type State = { flag: boolean }

function firstStep(state: State) {
  if (state.flag) { 
    secondStep(state)
    // this works though:
    // secondStep({ flag: state.flag })
  }
}

function secondStep(state: { flag: true }) {}

3: type State = { flag: boolean }
                    ^ boolean. Expected boolean literal `true`
13: function secondStep(state: { flag: true }) {}
                                   ^ boolean literal `true`

Flow知道它可以将state.flag细化为true,但它不知道state可以细化为{ flag: true }。这是预期的吗?

1 个答案:

答案 0 :(得分:1)

与表面看起来很好的许多子类型关系一样,这可以通过可变性来破坏。 secondStep可以保留对state的引用,firstStep可以稍后将state.flag更改为false

但是,如果您使用disjoint unions:

,这确实有效
type State = { flag: true } | { flag: false };

tryflow

您可能会发现,不相交的联盟最适合您的用例,因为根据标志的值,您可以在State对象中拥有不同的属性。

请注意,在这种情况下,Flow不允许您将state.flag设置为false,因此优化可以保留在secondStep