如何使用Flow导出动作创建者返回值的类型?

时间:2018-10-22 06:09:19

标签: javascript reactjs redux flowtype flow-typed

我目前正在导出2个动作创建者:

export const login = (payload: $PropertyType<Actions.Login, 'payload'>): Actions.Login => ({
  type: LOGIN,
  payload,
})

export const logout = (payload: $PropertyType<Actions.Logout, 'payload'>): Actions.Logout => ({
  type: LOGOUT,
  payload,
})

这些是它们各自的`动作:

export type Login = {
  type: ActionType,
  payload: {
    username: string,
    password: string,
  },
}

export type Logout = {
  type: ActionType,
  payload: null,
}

在另一个文件中,我使用通配符语法导入创建者

import * as Actions from ...

然后我试图从这些动作中提取其返回类型的形状,以用作我的减速器的动作类型。

我想要获得的是以下内容(我认为,这是Flow期望满足reducers要求的– type属性):

type Action = { 
    login: { type: '', payload: '' }, 
    logout: { type: '', payload: '' } 
}

我已经达到了这个功能:

type Action = $ObjMap<typeof Actions, <V>(V) => $Call<V>>

哪个返回以下内容:

Action: type Action = { 
    login: Login,
    logout: Logout
}

实际上是那些创建者返回的动作。但是,reducer中的Flow不会在该操作中的type属性上得到响应。

Reducer看起来像这样:

const reducer = (state: State = initialState, action: Action): State => {
  switch (action.type) {
    case LOGIN:
      return { ...state }
    default:
      return state
  }
}

action.type处的错误是:

[flow] property `type` is missing in object type [1]. (References: [1])

任何帮助编写更好的通用函数的方法都将受到赞赏。谢谢。

1 个答案:

答案 0 :(得分:0)

首先,从包含动作创建者的模块中导入模块导出的类型:

import typeof * as ActionCreators from './actions'

这将是一个对象类型,因此$ObjMap实用程序帮助程序可用于将每个操作创建者映射为其返回值的类型。这里需要注意的是:

  • 确保操作创建者返回的操作A正确
  • 利用$Values获得所有确切动作类型的并集

以下内容应导致一个类型,该类型包含创建者返回的所有可能动作的并集,可以通过化简器中的{ type }属性轻松地对其进行细化:

type Action = $Values<$ObjMap<ActionCreators, <A>((...any[]) => A) => $Exact<A>>>

您可以在Try Flow上查看此示例,以查看实际操作。请注意,对于loginlogout操作类型,将操作类型字符串分配为空的默认情况是如何;(action.type: empty)会引起action.type === 'login'action.type === 'logout'具有的错误没有处理。