带有打字稿的 Redux Thunk [英] Redux Thunk with Typescript
问题描述
我正在学习 Typescript,并且正在尝试实现一个简单的 React/Redux 应用程序.当我使用同步操作时,它工作正常,但问题出在异步操作上.我正在关注官方的 redux 教程.
首先我声明会话的状态
导出接口 UserSessionState {登录:布尔值;}
然后我声明动作的接口
interface UpdateSessionAction {类型:'USER_LOGIN';有效载荷:布尔值;}
我用联合类型导出它们
导出类型 UserActionTypes = UpdateSessionAction;
然后我有实际的行动
<预><代码>导出函数 updateSession(loggedIn: UserSessionState) {返回 {类型:'USER_LOGIN',有效载荷:登录,};}我有一个假的api调用
function api() {返回 Promise.resolve(true);}
最后是登录
export const userLogin = (): ThunkAction<空白,{},{},任何动作>=>异步(调度:ThunkDispatch<{}, {}, AnyAction>)=>{const res = 等待 api();dispatch(updateSession({ login: res }));};
在reducer中我只是简单地初始化状态
initialState: UserSessionState = {loggedIn: false}
然后我为减速器做普通的 redux 东西.
最后在我的商店中调用用于检查状态的初始操作
store.dispatch(userLogin());
我不断收到此错误:
'ThunkAction, {}, {}, AnyAction>' 类型的参数不可分配给AnyAction"类型的参数.类型ThunkAction, {}, {}, AnyAction>"中缺少属性type"但在AnyAction"类型中是必需的.
我缺少一个 type
但我不知道我做错了什么.
简而言之:
您收到此错误是因为从您的 userLogin()
函数返回的是一个 ThunkAction
,缺少 type
为什么会这样?
dispatch 应该接受 AnyAction
类型的参数.AnyAction
是一个 redux 类型,它扩展了 Action
(有一个强制属性 type
).
这是来自当前的 redux 类型文件
export interface Action{类型:T}/*** 接受任何其他属性的 Action 类型.* 这主要是针对`Reducer`类型的使用.* 这不是`Action` 本身的一部分,以防止用户扩展`Action.*/导出接口 AnyAction 扩展 Action {//允许在动作中定义任何额外的属性.[额外道具:字符串]:任何}
如何解决?使用 ThunkDispatch
类型代替 redux 的标准 Dispatch
.以下示例以及更多示例可在 this Gist
const mapDispatchToProps = (dispatch: ThunkDispatch) =>{返回 {onRequestClick: (arg: any) =>调度(myAsyncAction(arg)),};}
另外,请参阅此文章,部分将调度映射到道具
I am learning Typescript and I am trying to implement a simple React/Redux app. When I use sync actions it works fine, but the problems are with the async action. I am following the official redux tutorial.
First I declare the state for the session
export interface UserSessionState {
loggedIn: boolean;
}
Then I declare the interface for the action
interface UpdateSessionAction {
type: 'USER_LOGIN';
payload: boolean;
}
I export them with Union Types
export type UserActionTypes = UpdateSessionAction;
Then I have the actual Action
export function updateSession(loggedIn: UserSessionState) {
return {
type: 'USER_LOGIN',
payload: loggedIn,
};
}
I have a fake api call
function api() {
return Promise.resolve(true);
}
And finally the login
export const userLogin = (): ThunkAction<
void,
{},
{},
AnyAction
> => async (dispatch: ThunkDispatch<{}, {}, AnyAction>) => {
const res = await api();
dispatch(updateSession({ loggedIn: res }));
};
In the reducer I simply initialize the state
initialState: UserSessionState = {loggedIn: false}
Then I do the normal redux stuff for the reducer.
Finally in my store I call the initial action for checking the state
store.dispatch(userLogin());
I keep getting this error:
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'.
I am missing a type
but I have no idea what I do wrong.
In short:
You get this error because what returned from your userLogin()
function is a ThunkAction
, which is missing type
Why this is happening?
dispatch should accept parameter of type AnyAction
.
AnyAction
is a redux type, which extends Action
(which have a mandatory property type
).
This is from the current 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
}
How to fix it?
Use ThunkDispatch
type instead of redux's standard Dispatch
. The following example and more can be found on this Gist
const mapDispatchToProps = (dispatch: ThunkDispatch<MyState, void, Action>) => {
return {
onRequestClick: (arg: any) => dispatch(myAsyncAction(arg)),
};
}
Also, see this article, section Map Dispatch to Props
这篇关于带有打字稿的 Redux Thunk的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!