Redux Toolkit - Argument of type 'AsyncThunkAction<>' is not assignable to parameter of type 'AnyAction'
Asked Answered
S

3

22

I'm moving my React / Redux application to Redux toolkit, and am following instructions given here.

My custom selector and dispatch, as per the documentation.

import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import { AppDispatch, RootState } from "@/index";

export const useMyDispatch = () => useDispatch<AppDispatch>();
export const useMySelector: TypedUseSelectorHook<RootState> = useSelector;

Type of useMyDispatch is useMyDispatch(): Dispatch<AnyAction>

Type GETALLPAGESACTION is

export type GETALLPAGESACTION = {
  pagesLoading?: boolean;
  pages?: PageType[] | null;
  error?: Error | null;
}

This is my very basic action:

export const getAllPages = createAsyncThunk<GETALLPAGESACTION, 
 string,
 { dispatch: AppDispatch; state: RootState; }>("pages/getAllPages", 
   async () => {
   const pagesRes = await axios.get("___");
   if (pagesRes) {
     const finalPages: PageType[] = [];
     pagesRes.data.forEach((page: PageType) => {
     finalPages.push(page);
   });
   return { pages: finalPages, pagesLoading: false };
 }
 return { pages: [], pagesLoading: false };
});

My store is a simple:

const appStore = configureStore({
  reducer: {
    pages: PagesReducer, // pagesSlice.reducer is default export
  },
});
export type RootState = ReturnType<typeof appStore.getState>;
export type AppDispatch = typeof appStore.dispatch;

But when I try to use getAllPages in my component I get the above error.

useEffect(() => {
  dispatch(getAllPages());  // Error here 
 }, []);

Argument of type 'AsyncThunkAction<GETALLPAGESACTION, string, { dispatch: Dispatch<AnyAction>; state: { pages: { pages: null; pagesLoading: boolean; }; }; }>' is not assignable to parameter of type 'AnyAction'.

I know this question has been asked several times, and I have tried adding those solutions, including trying to set an explicit middleware type, which controls the dispatch type, but none of that has worked. From what I can understand (I'm relatively new to Typescript), the dispatch type is not being inferred correctly here?

This is my slice

export const pagesSlice = createSlice({
  name: "pages",
  initialState,
  reducers: {},
  extraReducers: {
    [getAllPages.pending]: (state, action: PayloadAction<GETALLPAGESACTION>) =>   {
      state.pagesLoading = true;
    },
    [getAllPages.fulfilled]: (state, action: PayloadAction<GETALLPAGESACTION>) => {
      state.pages = action.payload.pages;
      state.pagesLoading = false;
    },
   [getAllPages.rejected]: (state, action: PayloadAction<GETALLPAGESACTION>) => {
      state.pagesLoading = false;
   },
 },
});
export default pagesSlice.reducer;

I could really use some help here, especially with an explanation of what is wrong here and what I should dig into further to understand this better. Thanks!

Splash answered 17/8, 2021 at 5:56 Comment(0)
I
28

Most of the time this is just a bug, caused by Redux 4.0.5 and Redux 4.1.0/4.1.1 being installed both somewhere in your node_modules.

Most of the time, this can be resolved by reinstalling react-redux, @types/react-redux and @reduxjs/toolkit.

If you are using yarn, you can also run yarn why redux and it will list you all installed versions and why they are installed.


Update June 2022:

The same also happens if you install react-redux in v.8 and still have @types/react-redux in v.7 installed. react-redux 8 ships with it's own type definitions - in that case please uninstall @types/react-redux.

Intrust answered 17/8, 2021 at 7:15 Comment(8)
Thank you!! You were spot on, I did have 4.0.5 and 4.1.1 installed, re-installing the mentioned packages resolved this issue.Splash
is there an issue opened in github about this? @IntrustCourthouse
@ChanwooPark what would we do about it? Release another version that adds even more to the confusion? In the end, people should never have multiple versions of the same library installed side by side as that can always cause TypeScript problems, but that's a package manager problem. We can't do anything about that.Intrust
@Intrust is there another possible reason why this occurs even tho only one 'redux' package is installed ? using redux version is 4.1.2Courthouse
@ChanwooPark if you are not using the typed dispatch hooks recommended in the RTK TypeScript quickstart docs or passing an array into middlewares of configureStore, accidentally removing the thunk middleware.Intrust
@ ChanwooPark don't use middlewares array, instead use (getDefaultMiddleware) => getDefaultMiddleware().concat(thunkMiddleware)Winch
Same error. But for me it was react-redux version. changed 8.0.1 to 7.2.6. "react-redux": "7.2.6", "@types/react-redux": "^7.1.24", "@reduxjs/toolkit": "^1.8.1",Sneaker
@Sneaker if you have react-redux>=8, you don't need @types/react-redux at all any more. Please just uninstall that and everything should be fine.Intrust
T
42

In my case I had to create useAppDispatch function and use it instead useDispatch in component from react-redux.

export type AppDispatch = typeof store.dispatch

export const useAppDispatch = () => useDispatch<AppDispatch>()
Tadpole answered 28/7, 2022 at 10:8 Comment(3)
This was also my issue. Documentation on this issue can be read hereStale
You might not need to wrap it into another function, but just type the useDispatch. In my case I did ` const dispatch = useDispatch<AppDispatch>()` inside my componentPondicherry
also my issue, for types to work with typescript need to do this, accidentally had useDispatch(); called instead of the useAppDispatch as per RTK docs.Bensky
I
28

Most of the time this is just a bug, caused by Redux 4.0.5 and Redux 4.1.0/4.1.1 being installed both somewhere in your node_modules.

Most of the time, this can be resolved by reinstalling react-redux, @types/react-redux and @reduxjs/toolkit.

If you are using yarn, you can also run yarn why redux and it will list you all installed versions and why they are installed.


Update June 2022:

The same also happens if you install react-redux in v.8 and still have @types/react-redux in v.7 installed. react-redux 8 ships with it's own type definitions - in that case please uninstall @types/react-redux.

Intrust answered 17/8, 2021 at 7:15 Comment(8)
Thank you!! You were spot on, I did have 4.0.5 and 4.1.1 installed, re-installing the mentioned packages resolved this issue.Splash
is there an issue opened in github about this? @IntrustCourthouse
@ChanwooPark what would we do about it? Release another version that adds even more to the confusion? In the end, people should never have multiple versions of the same library installed side by side as that can always cause TypeScript problems, but that's a package manager problem. We can't do anything about that.Intrust
@Intrust is there another possible reason why this occurs even tho only one 'redux' package is installed ? using redux version is 4.1.2Courthouse
@ChanwooPark if you are not using the typed dispatch hooks recommended in the RTK TypeScript quickstart docs or passing an array into middlewares of configureStore, accidentally removing the thunk middleware.Intrust
@ ChanwooPark don't use middlewares array, instead use (getDefaultMiddleware) => getDefaultMiddleware().concat(thunkMiddleware)Winch
Same error. But for me it was react-redux version. changed 8.0.1 to 7.2.6. "react-redux": "7.2.6", "@types/react-redux": "^7.1.24", "@reduxjs/toolkit": "^1.8.1",Sneaker
@Sneaker if you have react-redux>=8, you don't need @types/react-redux at all any more. Please just uninstall that and everything should be fine.Intrust
T
4

My issue was how I defined my store's middleware. In order for TypeScript to determine the store's actions, you must use .concat and .prepend rather than defining a new array with a spread operator. No idea why.

Good

const store = configureStore({
  // ...
  middleware: getDefaultMiddleware => 
    getDefaultMiddleware()
      .prepend(/* ... */)
      .concat(/* ... */),
    // ...
  ],
  // ...
})

Bad

const store = configureStore({
  // ...
  middleware: getDefaultMiddleware => [
    // ...
    ...getDefaultMiddleware(),
    // ...
  ],
  // ...
})
Thomasinathomasine answered 14/7, 2023 at 23:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.