question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Typescript issues when adding custom middleware

See original GitHub issue

From the docs, I can get the type of dispatch by using typeof store.dispatch, this works well with the default middlewares. However, when I add my custom middleware, the inferred type of dispatch becomes Dispatch<AnyAction>. My question is, how can I properly type the custom middleware to make everything work together?

Here is the code for my store set up:

import { configureStore, getDefaultMiddleware, Action } from '@reduxjs/toolkit';
import { ThunkAction } from 'redux-thunk';
import { createLogger } from 'redux-logger';

import rootReducer, { RootState } from './rootReducer';

const middleware = [...getDefaultMiddleware<RootState>()];

if (process.env.NODE_ENV === 'development') {
  middleware.push(createLogger());
}

function configStore(initialState: any) {
  const store = configureStore({
    reducer: rootReducer,
    middleware,
    preloadedState: initialState,
  });

  if (process.env.NODE_ENV === 'development' && module.hot) {
    module.hot.accept('./rootReducer', () => {
      const newRootReducer = require('./rootReducer').default;
      store.replaceReducer(newRootReducer);
    });
  }

  return store;
}

export type AppDispatch = ReturnType<typeof configStore>['dispatch'];

export type AppThunk = ThunkAction<void, RootState, unknown, Action<string>>;

export default configStore;

with this setup, the inferred type of dispatch is

Screen Shot 2020-02-18 at 12 09 57

when I add my custom middleware, I just change

const middleware = [...getDefaultMiddleware<RootState>()];

to

const middleware = [...getDefaultMiddleware<RootState>(), customMiddleware];

then the inferred dispatch becomes Screen Shot 2020-02-18 at 12 12 07

This will cause ts to complain when I dispatch a thunk action Screen Shot 2020-02-18 at 12 15 24

Here is how I define my custom middleware

const customMiddleware: Middleware<{}, RootState> = store => next => action => {
  console.log(store.getState());
  const res = next(action);
  console.log(res);
  return res;
};

I have tried the suggestions in the doc but it does not solve the problem. https://redux-toolkit.js.org/usage/usage-with-typescript/#correct-typings-for-the-dispatch-type

Could someone help me?

note: I’m using version 1.2.4

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:13
  • Comments:10 (3 by maintainers)

github_iconTop GitHub Comments

11reactions
0xdevaliascommented, Jul 12, 2021

In case anyone ends up here from google like I did, my issue was that the middleware I was adding (LogRocket.reduxMiddleware()) returned it’s type as any, which broke thunks as described above.

For me, the simplest solution I came up with was to use as ReturnType<typeof getDefaultMiddleware> for it (since it’s the rightmost middleware anyway):

Cut down example from my code:

export const store = configureStore({
  // ..snip.. 

  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(
      LogRocket.reduxMiddleware() as ReturnType<typeof getDefaultMiddleware>
    ),

  // ..snip.. 
});
2reactions
TylerShincommented, Mar 3, 2020

If you have to change the order of middlewares, you should annotate the middlewares type manually. For example,

 const middleware: Array<Middleware<{}, AppState> | ThunkMiddleware<AppState, AnyAction, { axios: AxiosInstance }>> = [
    ...defaultMiddleware,
    ReduxNotifier,
    setUserToTracker,
    loggerMiddleware,
  ];
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to type redux thunk with middleware in typescript
The Redux docs "Usage with TypeScript" page specifically covers typing middleware and thunks: A custom middleware would look like:
Read more >
Usage With TypeScript - Redux Toolkit
So if you add correctly typed middlewares, dispatch should already be correctly typed.
Read more >
How to extend the Express Request object in TypeScript
Let's learn how to extend the Request type in TypeScript to make its instances store custom data you can use at the controller...
Read more >
Creating React Apps With Redux Toolkit and RTK Query - Toptal
Next, we will add custom middleware for handling 401 responses by simply ... to provide excellent developer experience with TypeScript, ...
Read more >
AWS SDK for JavaScript v3
Here's an example of adding a custom header using middleware: ... Issues you open will be evaluated, and included in our roadmap for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found