@Raey

Как исправить ошибку «TS2769: No overload matches this call.» при dispatch асинхронного экшена?

Никак не могу понять в чем проблема, ThunkAction вроде как корректно типизировал. При диспатче проверки авторизации в index.js вылазит ошибка:
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;
  }
};
  • Вопрос задан
  • 8309 просмотров
Решения вопроса 1
@Raey Автор вопроса
Вроде разобрался. Нужно было задать корректные типы в вызове applyMiddleware (у меня это вообще не было сделано).
Вот пример:
const store = createStore(
  rootReducer,
  composeWithDevTools(
    applyMiddleware(
      thunk.withExtraArgument(api) as ThunkMiddleware<
        GlobalState,
        AllReduxActions,
        AxiosInstance
      >,
    ),
  ),
);


А вот где посмотрел: https://github.com/reduxjs/redux-thunk/blob/master...
Надеюсь, будет кому-нибудь полезно.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы