R
R
Raey2021-01-25 20:16:48
typescript
Raey, 2021-01-25 20:16:48

How to fix "TS2769: No overload matches this call." when dispatching an asynchronous action?

I just can’t understand what the problem is, ThunkAction seems to be correctly typed. When dispatching the authorization check in index.js, an error pops up:

spoiler
TS2769: No overload matches this call.   Overload 1 of 3, '(action: { type: "FINISH_AUTHORIZATION"; payload: boolean; } | { type: "SET_AUTHORIZATION_STATUS"; payload: boolean; } | { type: "GET_USER_DATA"; payload: UserLogged; }): { ...; } | { ...; } | { ...; }', gave the following error.     Argument of type 'ThunkAction, CombinedState<{ USER: { authorizationStatus: boolean; user: UserLogged; isAuthorizationLoading: boolean; }; }>, AxiosInstance, { ...; } | ... 1 more ... | { ...; }>' is not assignable to parameter of type '{ type: "FINISH_AUTHORIZATION"; payload: boolean; } | { type: "SET_AUTHORIZATION_STATUS"; payload: boolean; } | { type: "GET_USER_DATA"; payload: UserLogged; }'.       Type 'ThunkAction, CombinedState<{ USER: { authorizationStatus: boolean; user: UserLogged; isAuthorizationLoading: boolean; }; }>, AxiosInstance, { ...; } | ... 1 more ... | { ...; }>' is missing the following properties from type '{ type: "GET_USER_DATA"; payload: UserLogged; }': type, payload   Overload 2 of 3, '(action: AnyAction): AnyAction', gave the following error.     Argument of type 'ThunkAction, CombinedState<{ USER: { authorizationStatus: boolean; user: UserLogged; isAuthorizationLoading: boolean; }; }>, AxiosInstance, { ...; } | ... 1 more ... | { ...; }>' is not assignable to parameter of type 'AnyAction'.       Property 'type' is missing in type 'ThunkAction, CombinedState<{ USER: { authorizationStatus: boolean; user: UserLogged; isAuthorizationLoading: boolean; }; }>, AxiosInstance, { ...; } | ... 1 more ... | { ...; }>' but required in type 'AnyAction'.   Overload 3 of 3, '(asyncAction: ThunkAction, {}, AxiosInstance, AnyAction>): Promise', gave the following error.     Argument of type 'ThunkAction, CombinedState<{ USER: { authorizationStatus: boolean; user: UserLogged; isAuthorizationLoading: boolean; }; }>, AxiosInstance, { ...; } | ... 1 more ... | { ...; }>' is not assignable to parameter of type 'ThunkAction, {}, AxiosInstance, AnyAction>'.       Type '{}' is not assignable to type 'CombinedState<{ USER: { authorizationStatus: boolean; user: UserLogged; isAuthorizationLoading: boolean; }; }>'.         Property 'USER' is missing in type '{}' but required in type '{ USER: { authorizationStatus: boolean; user: UserLogged; isAuthorizationLoading: boolean; }; }'.


index.ts:
store.dispatch(UserOperation.checkAuth()); // Тут ошибка

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root"),
);


reducer.ts:
export const rootReducer = combineReducers({
  // DATA: data,
  // APP: app,
  USER: user,
});

export type GlobalState = ReturnType<typeof rootReducer>;

export type InferActionsTypes<T> = T extends { [key: string]: infer U }
  ? U
  : never;

export type BaseThunkActionType<A extends Action = Action> = ThunkAction<
  Promise<void>,
  GlobalState,
  AxiosInstance,
  A
>;


user.ts:
type UserActionTypes = ReturnType<InferActionsTypes<typeof ActionCreator>>;
type ThunkActionType = BaseThunkActionType<UserActionTypes>;

export const initialState = {
  authorizationStatus: false as boolean,
  user: {
    id: -1,
    email: ``,
    isPro: false,
    avatar: ``,
    name: ``,
  } as UserLogged,
  isAuthorizationLoading: true as boolean,
};

type InitialStateType = typeof initialState;

export const ActionType = {
  SET_AUTHORIZATION_STATUS: `SET_AUTHORIZATION_STATUS`,
  GET_USER_DATA: `GET_USER_DATA`,
  FINISH_AUTHORIZATION: `FINISH_AUTHORIZATION`,
} as const;

export const ActionCreator = {
  finishAuthorizationLoading: () => {
    return {
      type: ActionType.FINISH_AUTHORIZATION,
      payload: false,
    };
  },

  setAuthorizationStatus: (status: boolean) => {
    return {
      type: ActionType.SET_AUTHORIZATION_STATUS,
      payload: status,
    };
  },

  getUserData: (userData: UserLogged) => {
    return {
      type: ActionType.GET_USER_DATA,
      payload: userData,
    };
  },
};

export const Operation = {
  checkAuth: (): ThunkActionType => async (
    dispatch,
    getState,
    api,
  ): Promise<void> => {
    try {
      const response = await api.get(`/login`);
      dispatch(ActionCreator.setAuthorizationStatus(true));
      dispatch(ActionCreator.getUserData(createUser(response.data)));
      dispatch(ActionCreator.finishAuthorizationLoading());
    } catch (e) {
      dispatch(ActionCreator.setAuthorizationStatus(false));
      dispatch(ActionCreator.finishAuthorizationLoading());
    }
  },

  login: (authData: LoginData): ThunkActionType => async (
    dispatch,
    getState,
    api,
  ): Promise<void> => {
    const response = await api.post(`/login`, {
      email: authData.email,
      password: authData.password,
    });
    dispatch(ActionCreator.setAuthorizationStatus(true));
    dispatch(ActionCreator.getUserData(createUser(response.data)));
    history.push(`/`);
  },
};

export const reducer = (
  state = initialState,
  action: UserActionTypes,
): InitialStateType => {
  switch (action.type) {
    case ActionType.SET_AUTHORIZATION_STATUS:
      return { ...state, authorizationStatus: action.payload };
    case ActionType.GET_USER_DATA:
      return { ...state, user: action.payload };
    case ActionType.FINISH_AUTHORIZATION:
      return { ...state, isAuthorizationLoading: action.payload };
    default:
      return state;
  }
};

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
Raey, 2021-01-26
@Raey

Seems to have figured it out. It was necessary to set the correct types in the applyMiddleware call (I didn’t do this at all).
Here is an example:

const store = createStore(
  rootReducer,
  composeWithDevTools(
    applyMiddleware(
      thunk.withExtraArgument(api) as ThunkMiddleware<
        GlobalState,
        AllReduxActions,
        AxiosInstance
      >,
    ),
  ),
);

And here's where I looked: https://github.com/reduxjs/redux-thunk/blob/master...
I hope it will be useful to someone.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question