我很惊讶地看到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 }
。这是预期的吗?
答案 0 :(得分:1)
与表面看起来很好的许多子类型关系一样,这可以通过可变性来破坏。 secondStep
可以保留对state
的引用,firstStep
可以稍后将state.flag
更改为false
。
但是,如果您使用disjoint unions:
,这确实有效type State = { flag: true } | { flag: false };
(tryflow)
您可能会发现,不相交的联盟最适合您的用例,因为根据标志的值,您可以在State
对象中拥有不同的属性。
请注意,在这种情况下,Flow不允许您将state.flag
设置为false
,因此优化可以保留在secondStep
。