带有打字稿的 Redux Thunk

Kai*_*oze 12 javascript typescript reactjs redux

我正在学习 Typescript,并且正在尝试实现一个简单的 React/Redux 应用程序。当我使用同步操作时,它工作正常,但问题出在异步操作上。我正在关注官方的 redux 教程。

首先我声明会话的状态

export interface UserSessionState {
  loggedIn: boolean;
}
Run Code Online (Sandbox Code Playgroud)

然后我声明动作的接口

interface UpdateSessionAction {
  type: 'USER_LOGIN';
  payload: boolean;
}
Run Code Online (Sandbox Code Playgroud)

我用联合类型导出它们

export type UserActionTypes = UpdateSessionAction;

然后我有实际的行动


export function updateSession(loggedIn: UserSessionState) {
  return {
    type: 'USER_LOGIN',
    payload: loggedIn,
  };
}
Run Code Online (Sandbox Code Playgroud)

我有一个假的 api 调用

function api() {
  return Promise.resolve(true);
}
Run Code Online (Sandbox Code Playgroud)

最后登录

export const userLogin = (): ThunkAction<
  void,
  {},
  {},
  AnyAction
> => async (dispatch: ThunkDispatch<{}, {}, AnyAction>) => {
  const res = await api();
  dispatch(updateSession({ loggedIn: res }));
};
Run Code Online (Sandbox Code Playgroud)

在减速器中,我只是初始化状态

initialState: UserSessionState = {loggedIn: false}

然后我为减速器做正常的 redux 东西。

最后在我的商店中,我调用了用于检查状态的初始操作

store.dispatch(userLogin());
Run Code Online (Sandbox Code Playgroud)

我不断收到此错误:

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'.
Run Code Online (Sandbox Code Playgroud)

我错过了,type但我不知道我做错了什么。

yuv*_*.bl 17

简而言之:

您收到此错误是因为从您的userLogin()函数返回的是 a ThunkAction,而缺少了type

为什么会发生这种情况?

dispatch 应该接受 type 的参数AnyActionAnyAction是一种 redux 类型,它扩展Action(具有强制属性 type)。

这是来自当前的redux 类型文件

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
}
Run Code Online (Sandbox Code Playgroud)

如何解决? 使用ThunkDispatchtype 而不是 redux 的标准Dispatch。可以在此 Gist上找到以下示例和更多示例

const mapDispatchToProps = (dispatch: ThunkDispatch<MyState, void, Action>) => {
  return {
    onRequestClick: (arg: any) => dispatch(myAsyncAction(arg)),
  };
}

Run Code Online (Sandbox Code Playgroud)

另外,请参阅这篇文章,部分Map Dispatch to Props