首页 > 解决方案 > 通过条件缩小联合类型

问题描述

假设我有以下类型:

type MyCustomAction = {|
  type: "MY_CUSTOM_ACTION",
  payload: string
|}

type MyCustomAction2 = {|
  type: "MY_CUSTOM_ACTION2",
  data: number
|}

type CustomAction = MyCustomAction2 | MyCustomAction


const MyCustomFunction = (action: CustomAction): void => {
  const type = action.type

  if (type === "MY_CUSTOM_ACTION") {
    let payload = action.payload
  } else if (type === "MY_CUSTOM_ACTION2") {
    let data = action.data
  }
}

这失败了:

21:         let payload = action.payload                                 ^ Cannot get `action.payload` because property `payload` is missing in `MyCustomAction2` [1].
References:
17:     const MyCustomFunction = (action: CustomAction): void => {
                                          ^ [1]
23:         let data = action.data                              ^ Cannot get `action.data` because property `data` is missing in `MyCustomAction` [1].
References:
17:     const MyCustomFunction = (action: CustomAction): void => {
                                          ^ [1]

Link to try flow: https://flow.org/try/#0FDAuE8AcFMAIFlwGECuBnUB7AtgQQMagCWmAdrALywDeAPsLLBDAFywBE8AmgPpICqAZQAqAeXg9cSYQElRAOXYAaBrEgBDcABtM6gCZsMAJyKkA5sFoBfVYzBQ4iVBhwFiZAEyUa9Rn-8BgUEBzNBsnLwCIuKS0nLyHsq2wSmpjHrqoOpspCjYAEbQRslppQHWycmhsM5YeIQk5FRO6HVujV6+AS0u9e6kIMn4ZBgIyK04AGIopA1k3gAU6nOkbLWuKwCUbABumER6lAB8NCWww6Sj1VTL-QB0oSCBRABmsAvXFFQRfEJiElJZAp2JtTsEtNBQGpNDp9N5bo07hptLo9GcrLBoFo0HBXu9Pt9uL9ogC4gpEqDqGdGBCoRksvCVnd6ep0ckbMAgA

是否可以像这样切换类型?为什么流无法检测到 MyCustomAction 将始终具有有效负载?

标签: javascriptflowtype

解决方案


似乎是流编译器中的一个问题,但是如果您直接使用对象字段,它可以正常工作:)

type MyCustomAction = {|
  type: "MY_CUSTOM_ACTION",
  payload: string
|}

type MyCustomAction2 = {|
  type: "MY_CUSTOM_ACTION2",
  data: number
|}

type CustomAction = MyCustomAction2 | MyCustomAction

const MyCustomFunction = (action: CustomAction): void => {
    if (action.type === 'MY_CUSTOM_ACTION') {
        const payload = action.payload;
    } else if (action.type === 'MY_CUSTOM_ACTION2') {
        const data = action.data;
    }
};

尝试


推荐阅读