TS2345: аргумент типа AsyncThunkAction<void | AddItem, ItemInput, AsyncThunkConfig>» невозможно назначить параметру типа AnyAction

В моем фрагменте я определил действие следующим образом: https://github.com/jasonabanico/RedGranite/blob/main/src/Client/RedGranite.Client.Web/src/app/containers/ItemPage/itemPageSlice.ts

export const addItem = createAsyncThunk(
    'itemPage/addItem',
    async (itemInput: ItemInput) => {
        return await itemService
            .addItem(itemInput)
            .catch((err: any) => {
                console.info("Error:", err);
            });
    },
)

Я также определил useAppDispatch как: https://github.com/jasonabanico/RedGranite/blob/main/src/Client/RedGranite.Client.Web/src/app/hooks.ts

export const useAppDispatch = () => useDispatch<AppDispatch>();

Я использую оба вышеперечисленных варианта следующим образом: https://github.com/jasonabanico/RedGranite/blob/main/src/Client/RedGranite.Client.Web/src/app/containers/ItemPage/addItemPage.tsx

const dispatch = useAppDispatch();
...
dispatch(addItem(itemInput));

Я получаю следующую ошибку:

TS2345: аргумент типа AsyncThunkAction<void | AddItem, ItemInput, AsyncThunkConfig>» нельзя назначить параметру типа AnyAction. 21 | длинное описание 22 | };

23 | отправка (addItem (itemInput)); | ^^^^^^^^^^^^^^^^^^^ 24 | };

Что не так в моих определениях? Почему я не могу использовать addItem при отправке?

ОБНОВЛЯТЬ:

Код в репозитории обновлен до этого, но возникает та же ошибка.

export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();

ОБНОВЛЯТЬ:

Для тиражирования в Codesandbox.

  • Открыть терминал
  • источник компакт-диска
  • компакт-диск клиент
  • компакт-диск RedGranite.Client.Web
  • установка npm
  • npm запустить сборку
  • см. ошибку сборки

🤔 А знаете ли вы, что...
С React можно легко интегрировать с другими библиотеками и фреймворками.


2
107
3

Ответы:

Согласно текущей документации кажется, что ваши хуки useAppDispatch и useAppSelector не совсем правильные.

  • Для useSelector это избавляет вас от необходимости каждый раз вводить (state: RootState).

  • Для useDispatch тип Dispatch по умолчанию не знает о переходниках. Чтобы правильно отправить thunk, вам нужно использовать специальный индивидуальный AppDispatch тип из магазина, который включает в себя типы промежуточного программного обеспечения thunk и используйте его с useDispatch. Добавление предварительно набранный крючок useDispatch не позволит вам забыть импортировать AppDispatch там, где это необходимо.

    import { useDispatch, useSelector } from 'react-redux'
    import type { RootState, AppDispatch } from './store'
    
    // Use throughout your app instead of plain `useDispatch` and `useSelector`
    export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
    export const useAppSelector = useSelector.withTypes<RootState>()
    

Обновите файл src/Client/RedGranite.Client.Web/src/app/hooks.ts до текущего предложения:

import { useDispatch, useSelector } from 'react-redux';
import type { RootState, AppDispatch } from './store';

// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();

Кажется, вы возвращаете неправильные данные в своей функции действия. Поэтому я думаю, что должно быть так:


export const addItem = createAsyncThunk(
  "itemPage/addItem",
  async (itemInput: ItemInput, { rejectWithValue }) => {
    try {
      const data = await itemService.addItem(itemInput);
      return data;
    } catch (error: any) {
      // if there is an error, it would get rejected status in your extraReducer function
      if (error.response.data) return rejectWithValue(error.response.data);
    }
  }
);

Надеюсь, это может быть полезно.


Решено

Наконец-то я нашел причину. Это произошло потому, что вы определили промежуточное программное обеспечение отдельно, введя anystore.ts. Итак, я исправил вашу проблему, изменив ваш файл store.ts следующим образом:

    import {
      configureStore,
      ThunkAction,
      Action
    } from "@reduxjs/toolkit";
    import homePageReducer from "./containers/HomePage/homePageSlice";
    import itemPageReducer from "./containers/ItemPage/itemPageSlice";
    import ReduxLogger from "redux-logger";
    
    export const store = configureStore({
      middleware:(getDefaultMiddleware) =>
        getDefaultMiddleware().concat(ReduxLogger),
      reducer: {
        homePage: homePageReducer,
        itemPage: itemPageReducer,
      },
    });
    
    export type AppDispatch = typeof store.dispatch;
    export type RootState = ReturnType<typeof store.getState>;
    export type AppThunk<ReturnType = void> = ThunkAction<
      ReturnType,
      RootState,
      unknown,
      Action<string>
    >;

Тип AppDispatch должен был быть ThunkDispatch<any, undefined, UnknownAction> & Dispatch<UnknownAction>, но это был просто Dispatch<UnknownAction>. Так что это не сработало. Это из-за типа getDefaultMiddleware было any.