TLDR:我在Try Flow(link)中建模了我的问题。你能帮我解决一下吗?
问题的完整描述:
在Redux reducer中,我选择了三个动作。一个动作可以具有任何类型,但其独特的特征是它在其有效载荷中具有特定字段(在该示例中为payload.entities.items
)。另外两个动作具有特定的类型来区分它们,并且具有不同的有效载荷:
const FOO = 'FOO'
const BAR = 'BAR'
type ActionWithEntities = {|
type: string,
payload: {|
entities: {|
items: {
[string]: string
}
|}
|}
|}
type ActionWithFoo = {|
type: typeof FOO,
payload: {|
foo: string
|}
|}
type ActionWithBar = {|
type: typeof BAR,
payload: {|
bar: string
|}
|}
type Action =
| ActionWithEntities
| ActionWithFoo
| ActionWithBar
根据动作,我想在减速器中做任何适当的事情(并不重要):
function reducer(state: State, action: Action) {
if (action.payload && action.payload.entities && action.payload.entities.items) {
return Object.assign({}, state, action.payload.entities.items);
}
switch(action.type) {
case FOO:
const foo = action.payload.foo;
return { foo }
case BAR: {
const bar = action.payload.bar;
return { bar }
}
default:
return state;
}
}
我的问题是,Flow没有看到if语句负责第一个操作(因为其他操作在其有效负载中没有entities
字段),并在switch语句中抱怨我尝试使用的字段(在此示例中为foo
或bar
)在第一个操作中不存在。
让Flow满意的正确方法是什么?
答案 0 :(得分:3)
流程并不是这样的原因是因为ActionWithEntities的类型字段是字符串类型,这意味着它可以具有值FOO或BAR。现在,您的逻辑将阻止它击中开关/案例,但流程无法遵循该逻辑并改进类型。解决它的一种方法是显式键入ActionWithEntities
的类型字段类似
type ActionWithEntities = {|
type: 'OTHER' | 'OTHER2' | 'OTHER3',
payload: {|
entities: {|
items: {
[string]: string
}
|}
|}
|}