我目前正在导出 2 个 Action 创建器:
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,
})
这些是它们各自的“ Action ”:
export type Login = {
type: ActionType,
payload: {
username: string,
password: string,
},
}
export type Logout = {
type: ActionType,
payload: null,
}
在另一个文件中,我使用通配符语法导入创建者
import * as Actions from ...
然后我尝试从这些操作中提取它们返回类型的形状,以用作我的 reducer 的操作类型。
我想要获得的是以下内容(我认为,因为我假设这是 Flow 期望满足 reducer 要求的东西——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
}
这确实是那些创作者返回的 Action 。但是,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])
非常感谢任何有助于编写更好的通用函数的帮助。谢谢。
最佳答案
首先,从包含 Action 创建者的模块中导入模块导出的类型:
import typeof * as ActionCreators from './actions'
这将是一个对象类型,所以 $ObjMap
实用程序助手可用于将每个 Action 创建者映射到它的返回值类型。这里需要注意的是:
- 确保从 Action 创建者返回的 Action
A
是准确的 - 利用
$Values
获得所有确切 Action 类型的联合
以下应该产生一个类型,其中包含创建者返回的所有可能操作的联合,可以很容易地通过 reducer 中的 { type }
属性进行细化:
type Action = $Values<$ObjMap<ActionCreators, <A>((...any[]) => A) => $Exact<A>>>
您可以在 Try Flow 上查看此示例看到它在行动。请注意对于 login
和 logout
操作类型,将操作类型字符串指定为空的默认情况 ;(action.type: empty)
引发 action.type === 'login'
和 action.type === 'logout'
未被处理的错误。
关于javascript - 如何使用 Flow 导出 Action 创建者返回值的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52923259/