Reputation: 51
import { configureStore } from "@reduxjs/toolkit";
import testSlice from "./testSlice";
import {combineReducers} from "redux";
const rootReducer = combineReducers({test: testSlice})
export const store = configureStore({
reducer: rootReducer,
});
export type RootState = ReturnType<typeof rootReducer>
This is my current workaround in order to get the type of my root reducer. I'm reading the docs and I can't seem to find how to get my root reducer from the store if I was using slices to create the reducer in my configure store. It's just disappointing that I have to use combineReducers again while using redux-toolkit just to get my rootReducer type.
I'm looking for a code like this:
import { configureStore } from "@reduxjs/toolkit";
import testSlice from "./testSlice";
import userSlice from "./userSlice";
export const store = configureStore({
reducer: {test: testSlice, user: userSlice},
});
export type RootState = ReturnType<typeof store.getReducer()>
Upvotes: 5
Views: 6402
Reputation: 42198
Huan's answer is spot-on. It is very unlikely that you will actually need to access the root reducer type. You can get the state type without it. Their answer is the best solution to underlying problem.
If anyone reading this question would like to know how to derive the root reducer type from the store type, it can be done by using TypeScript conditional types. This is the same sort of logic that you see in the redux source code.
We can define a reusable utility type that gets the reducer type from the type of the store. It does this by accessing the types for the state S
and the action A
, which are both generic type parameters of the redux Store<S, A>
type. Then we apply those same generics to the Reducer<S, A>
type.
// Can be imported from 'redux' or from '@reduxjs/toolkit', both are the same.
import { Reducer, Store } from '@reduxjs/toolkit';
type ReducerFromStore<T> = T extends Store<infer S, infer A> ? Reducer<S, A> : never
You can use this utility type to get the root reducer type from a specific store instance.
export const store = configureStore({
reducer: {test: testSlice, user: userSlice},
});
export type RootReducer = ReducerFromStore<typeof store>;
Note: The exact type of the store
object created by configureStore
is the redux toolkit EnhancedStore
type. But this extends the core redux Store
type, so no special handling is needed.
Upvotes: 1
Reputation: 48
A better type for RootState would be as below:
export type RootState = ReturnType<typeof store.getState>
This implementation is included in the document. Please take time to read it.
If your intention of getting the rootReducer isn't only for defining the RootState type, you can simply named-export it from store file and then import it in your desired file to use.
// store.js
// ...
export const rootReducer = combineReducers({test: testSlice});
It's not a common and practical usage for the rootReducer to be imported and consumed in other places but the store file, where it will be used to configure the store object. Therefore, I think there's no point for Redux Toolkit to provide a way to access the rootReducer.
Upvotes: 2