Redux 流量:在减速器中的动作之间进行选择

Redux 流量:在减速器中的动作之间进行选择,redux,flowtype,Redux,Flowtype,TLDR:我已经在Try Flow()中建模了我的问题。你能帮我解决这个问题吗 问题的完整描述: 在Redux reducer中,我在三种操作之间进行选择。一个操作可以有任何类型,但其显著特征是其有效负载中有一个特定字段(payload.entities.items,在本例中为)。另外两个动作有特定的类型来区分它们,也有不同的有效载荷: const FOO = 'FOO' const BAR = 'BAR' type ActionWithEntities = {| type: string

TLDR:我已经在Try Flow()中建模了我的问题。你能帮我解决这个问题吗

问题的完整描述:

在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语句处理第一个操作(因为其他操作的有效负载中没有
实体
字段),并且在switch语句中抱怨第一个操作中没有我尝试使用的字段(
foo
bar


让流程快乐的正确方法是什么?

流程不喜欢这样的原因是因为ActionWithEntities的类型字段是string类型,这意味着它可以有值FOO或BAR。现在,您的逻辑将阻止它命中开关/案例,但flow无法遵循该逻辑并优化类型。解决此问题的一种方法是显式地为ActionWithEntities键入类型字段

大概是

type ActionWithEntities = {|
  type: 'OTHER' | 'OTHER2' | 'OTHER3',
  payload: {|
    entities: {|
      items: {
        [string]: string
      }
    |}
  |}
|}

那太不幸了。我认为当给定一组显式if语句时,Flow能够细化类型。你知道Flow是否有办法从字符串类型中排除某组字符串,这样我就不需要枚举
类型
字段中所有可能的字符串,而是说这个字段是一个既不是FOO也不是BAR的字符串?@azangru:我认为你不能从
字符串
类型中排除一些字符串。静态的打字检查是不可能的。