Home > other >  How to dynamically determine RootState type in redux toolkit with makeStore function
How to dynamically determine RootState type in redux toolkit with makeStore function

Time:10-12

I am trying to get the type of my redux store in order to declare the RootState type. Up until now I was creating and exporting a store instance as specified in the redux toolkit docs and faced no problems whatsoever, but now for various reasons I want to have a makeStore function to return a new store every time I call it.

My problem is that while I have a working implementation, the type of RootState is any which results in no autocomplete recommendations.

My code is the following:

import {
    configureStore,
    combineReducers,
    EnhancedStore,
    ConfigureStoreOptions,
} from '@reduxjs/toolkit';
import createSagaMiddleware from 'redux-saga';
import {
    persistStore,
    persistReducer,
    FLUSH,
    REHYDRATE,
    PAUSE,
    PERSIST,
    PURGE,
    REGISTER,
} from 'redux-persist';
import storage from 'redux-persist/lib/storage';

import { cartReducer } from '@hooks';

import appReducer from './reducer';
import rootSaga from './saga';

export const makeStore: (
    initialState?: ConfigureStoreOptions['preloadedState']
) => EnhancedStore = (initialState = {}) => {
    const persistConfig = {
        key: 'root',
        version: 1,
        storage,
    };

    const persistedReducer = persistReducer(
        persistConfig,
        combineReducers({ app: appReducer, cart: cartReducer })
    );

    const sagaMiddleware = createSagaMiddleware();

    const store = configureStore({
        reducer: persistedReducer,
        preloadedState: initialState,
        middleware: getDefaultMiddleware =>
            getDefaultMiddleware({
                thunk: false,
                serializableCheck: {
                    ignoredActions: [
                        FLUSH,
                        REHYDRATE,
                        PAUSE,
                        PERSIST,
                        PURGE,
                        REGISTER,
                    ],
                },
            }).concat(sagaMiddleware),
    });

    sagaMiddleware.run(rootSaga);

    return store;
};

const store = makeStore();
export const persistor = persistStore(store);
export type RootState = ReturnType<typeof store.getState>; // this is "any"
export type AppDispatch = typeof store.dispatch; // this is "Dispatch<AnyAction>"

export default store;

I think the most probable cause of the problem lies in EnhancedStore which is a generic and looks like that:

export interface EnhancedStore<S = any, A extends Action = AnyAction, M extends Middlewares<S> = Middlewares<S>> extends Store<S, A> {
    /**
     * The `dispatch` method of your store, enhanced by all its middlewares.
     *
     * @inheritdoc
     */
    dispatch: DispatchForMiddlewares<M> & Dispatch<A>;
}

I am not really sure what S is supposed to be, so I don't pass anything to it and it defaults to any.

My question is, what is the best way to get the store state type when using redux-toolkit and a makeStore function?

CodePudding user response:

Just remove your return type.

The real return type is much more nuanced and you are throwing that information out of the window by assigning one yourself.

export const makeStore: (
    initialState?: ConfigureStoreOptions['preloadedState']
) = (initialState = {}) => {
  • Related