带有 Typescript 的 Redux Thunk
Posted
技术标签:
【中文标题】带有 Typescript 的 Redux Thunk【英文标题】:Redux Thunk with Typescript 【发布时间】:2019-11-14 06:38:15 【问题描述】:我正在学习 Typescript,我正在尝试实现一个简单的 React/Redux 应用程序。当我使用同步操作时,它工作正常,但问题在于异步操作。我正在关注官方的 redux 教程。
首先我声明会话的状态
export interface UserSessionState
loggedIn: boolean;
然后我声明动作的接口
interface UpdateSessionAction
type: 'USER_LOGIN';
payload: boolean;
我用联合类型导出它们
export type UserActionTypes = UpdateSessionAction;
然后我有实际的行动
export function updateSession(loggedIn: UserSessionState)
return
type: 'USER_LOGIN',
payload: loggedIn,
;
我有一个虚假的 api 调用
function api()
return Promise.resolve(true);
最后是登录
export const userLogin = (): ThunkAction<
void,
,
,
AnyAction
> => async (dispatch: ThunkDispatch<, , AnyAction>) =>
const res = await api();
dispatch(updateSession( loggedIn: res ));
;
在reducer中我只是初始化状态
initialState: UserSessionState = loggedIn: false
然后我为 reducer 做正常的 redux 工作。
最后在我的商店中,我调用了检查状态的初始操作
store.dispatch(userLogin());
我不断收到此错误:
Argument of type 'ThunkAction<Promise<void>, , , AnyAction>' is not assignable to parameter of type 'AnyAction'.
Property 'type' is missing in type 'ThunkAction<Promise<void>, , , AnyAction>' but required in type 'AnyAction'.
我错过了type
,但我不知道我做错了什么。
【问题讨论】:
在更新会话中,您返回一个类型为 USER_LOGIN 的操作,但这不是界面中的字符串 - 您是否在其他地方声明过?如果不是,您将希望将其设为字符串 是的,这是一个导出的普通常量export const USER_LOGIN = 'USER_LOGIN';
,我编辑了我的问题只是为了清楚起见,谢谢
【参考方案1】:
简而言之:
您收到此错误是因为从您的userLogin()
函数返回的是ThunkAction
,缺少type
为什么会这样?
dispatch 应该接受AnyAction
类型的参数。
AnyAction
是一个 redux 类型,它扩展了 Action
(它有一个强制属性 type
)。
这是来自当前的redux types file
export interface Action<T = any>
type: T
/**
* An Action type which accepts any other properties.
* This is mainly for the use of the `Reducer` type.
* This is not part of `Action` itself to prevent users who are extending `Action.
*/
export interface AnyAction extends Action
// Allows any extra properties to be defined in an action.
[extraProps: string]: any
如何解决?
使用ThunkDispatch
类型而不是redux 的标准Dispatch
。以下示例及更多内容可以在this Gist 上找到
const mapDispatchToProps = (dispatch: ThunkDispatch<MyState, void, Action>) =>
return
onRequestClick: (arg: any) => dispatch(myAsyncAction(arg)),
;
另外,请参阅article,Map Dispatch to Props 部分
【讨论】:
感谢export function updateSession(loggedIn: UserSessionState)
的回答,但在这里我想说的是有效负载loggedIn
必须是UserSessionState 的形状,然后我就有了这里interface UpdateSessionAction type: 'USER_LOGIN'; payload: boolean;
的操作类型对吗?
谢谢!现在我得到Argument of type 'boolean' is not assignable to parameter of type 'UpdateSessionAction
,但无论如何我都会接受你的回答,因为它是正确的。我需要了解更多关于 typescript 的知识,也许我把事情直接转移到异步操作中。 :)以上是关于带有 Typescript 的 Redux Thunk的主要内容,如果未能解决你的问题,请参考以下文章
带有 Typescript 和 react-redux 的有状态组件:“typeof MyClass”类型的参数不可分配给 Component 类型的参数
react状态管理器(分模块)之redux和redux + react-redux + reducer和redux + react-redux + reducer分模块 + 异步操作redux-thu
如何将 Redux 4.0 TypeScript 绑定与 redux-thunk 一起使用
typescript + redux:在父组件中排除 redux props