我目前正在导出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])
任何帮助编写更好的通用函数的方法都将受到赞赏。谢谢。
答案 0 :(得分:0)
首先,从包含动作创建者的模块中导入模块导出的类型:
import typeof * as ActionCreators from './actions'
这将是一个对象类型,因此$ObjMap
实用程序帮助程序可用于将每个操作创建者映射为其返回值的类型。这里需要注意的是:
A
正确$Values
获得所有确切动作类型的并集以下内容应导致一个类型,该类型包含创建者返回的所有可能动作的并集,可以通过化简器中的{ type }
属性轻松地对其进行细化:
type Action = $Values<$ObjMap<ActionCreators, <A>((...any[]) => A) => $Exact<A>>>
您可以在Try Flow上查看此示例,以查看实际操作。请注意,对于login
和logout
操作类型,将操作类型字符串分配为空的默认情况是如何;(action.type: empty)
会引起action.type === 'login'
和action.type === 'logout'
具有的错误没有处理。