How to get typescript compiler to infer type of getDefaultMiddleware? Getting implicitly 'any' error

21 Views Asked by At

I'm getting an error:

Parameter 'getDefaultMiddleware' implicitly has an 'any' type.

My store code looks like this:

import { configureStore } from '@reduxjs/toolkit';
import uiStateReducer from './ui_state';
import logger from 'redux-logger';

const rootReducer = {
  uiState: uiStateReducer,
  middleware: (getDefaultMiddleware) => {
    return getDefaultMiddleware.concat(logger)
  }
};

const store = configureStore({ reducer: rootReducer });

I've checked the Redux-Toolkit Github issues page for anyone who's having this issue (couldn't find anything) and all the code snippets of other issues showing the (getDefaultMiddleware) => { function do not explicitly type the getDefaultMiddleware. Can someone point me to how getDefaultMiddleware can be inferred?

1

There are 1 best solutions below

1
Drew Reese On

Redux middleware is added to the store when it is created, not as a reducer function. It seems that Typescript is reading this as a reducer function and letting you know the "state" argument isn't explicitly typed.

const rootReducer = {
  uiState: uiStateReducer,
  middleware: (getDefaultMiddleware) => { // <-- thinks this is a reducer function!
    return getDefaultMiddleware.concat(logger)
  }
};

See middleware

middleware

A callback which will receive getDefaultMiddleware as its argument, and should return a middleware array.

If this option is provided, it should return all the middleware functions you want added to the store. configureStore will automatically pass those to applyMiddleware.

If not provided, configureStore will call getDefaultMiddleware and use the array of middleware functions it returns.

For more details on how the middleware parameter works and the list of middleware that are added by default, see the getDefaultMiddleware docs page.

TUPLE

Typescript users are required to use a Tuple instance (if not using a getDefaultMiddleware result, which is already a Tuple), for better inference.

import { configureStore, Tuple } from '@reduxjs/toolkit'

configureStore({
  reducer: rootReducer,
  middleware: () => new Tuple(additionalMiddleware, logger),
})

Javascript-only users are free to use a plain array if preferred.

If using the getDefaultMiddleware function then the types are inferred more easily.

import { configureStore } from '@reduxjs/toolkit';
import uiStateReducer from './ui_state';
import logger from 'redux-logger';

const rootReducer = {
  uiState: uiStateReducer,
};

const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware.concat(logger),
});

If Typescript users are just adding their own middleware then they must return a Tuple.

import { configureStore } from '@reduxjs/toolkit';
import uiStateReducer from './ui_state';
import logger from 'redux-logger';

const rootReducer = {
  uiState: uiStateReducer,
};

const store = configureStore({
  reducer: rootReducer,
  middleware: () => new Tuple(logger),
});