next-redux-wrapper
next-redux-wrapper copied to clipboard
typescript error in configureStore
Typescript unhappy with the type but not sure how to adjust it.
Here is my code:
const allReducers = {
App: appReducer,
ThemeSwitcher: themeSwitcherReducer,
Auth: authReducer,
[articleApi.reducerPath]: articleApi.reducer,
};
const combinedReducer = combineReducers(allReducers);
const reducer = (state: ReturnType<typeof combinedReducer>, action: AnyAction) => {
console.log(`reducer action ${action.type}`, action);
if (action.type === HYDRATE) {
const nextState = {
...state, // use previous state
...action.payload, // apply delta from hydration
};
return nextState;
} else {
return combinedReducer(state, action);
}
};
export const store = configureStore({
reducer: reducer,
middleware: getDefaultMiddleware => {
return getDefaultMiddleware().concat(articleApi.middleware);
},
});
export const initStore = () => {
return store;
};
type Store = ReturnType<typeof initStore>;
export type AppDispatch = Store['dispatch'];
export type RootState = ReturnType<Store['getState']>;
export type AppThunk<ReturnType = void> = ThunkAction<ReturnType, RootState, unknown, Action<string>>;
export const wrapper = createWrapper(initStore, { debug: process.env.NODE_ENV === 'development' });
The error is on configureStore param reducer: reducer:
Type '(state: ReturnType<typeof combinedReducer>, action: AnyAction) => any' is not assignable to type 'Reducer<CombinedState<{ App: AppState; ThemeSwitcher: { isActivated: boolean; changeThemes: IThemeElementOptions; topbarTheme: IThemeElementOptions; sidebarTheme: IThemeElementOptions; layoutTheme: IThemeElementOptions; }; Auth: Auth; articleApi: CombinedState<...>; }>, AnyAction> | ReducersMapObject<...>'.
Type '(state: ReturnType<typeof combinedReducer>, action: AnyAction) => any' is not assignable to type 'Reducer<CombinedState<{ App: AppState; ThemeSwitcher: { isActivated: boolean; changeThemes: IThemeElementOptions; topbarTheme: IThemeElementOptions; sidebarTheme: IThemeElementOptions; layoutTheme: IThemeElementOptions; }; Auth: Auth; articleApi: CombinedState<...>; }>, AnyAction>'.
Types of parameters 'state' and 'state' are incompatible.
Type 'CombinedState<{ App: AppState; ThemeSwitcher: { isActivated: boolean; changeThemes: IThemeElementOptions; topbarTheme: IThemeElementOptions; sidebarTheme: IThemeElementOptions; layoutTheme: IThemeElementOptions; }; Auth: Auth; articleApi: CombinedState<...>; }> | undefined' is not assignable to type 'CombinedState<{ App: AppState; ThemeSwitcher: { isActivated: boolean; changeThemes: IThemeElementOptions; topbarTheme: IThemeElementOptions; sidebarTheme: IThemeElementOptions; layoutTheme: IThemeElementOptions; }; Auth: Auth; articleApi: CombinedState<...>; }>'.
Type 'undefined' is not assignable to type 'CombinedState<{ App: AppState; ThemeSwitcher: { isActivated: boolean; changeThemes: IThemeElementOptions; topbarTheme: IThemeElementOptions; sidebarTheme: IThemeElementOptions; layoutTheme: IThemeElementOptions; }; Auth: Auth; articleApi: CombinedState<...>; }>'.
Type 'undefined' is not assignable to type 'EmptyObject'.
I probably just need casting but I am not sure of the correct type... Any help much appreciated :)
Looks like you shouldn't use the combinedReducer
Maybe something like this:
export const store = configureStore({
reducer: {
App: appReducer,
ThemeSwitcher: themeSwitcherReducer,
Auth: authReducer,
[articleApi.reducerPath]: articleApi.reducer,
},
});
export const initStore = () => {
return store;
};
type Store = ReturnType<typeof initStore>;
export type AppDispatch = Store['dispatch'];
export type RootState = ReturnType<Store['getState']>;
export type AppThunk<ReturnType> = ThunkAction<
ReturnType,
RootState,
unknown,
Action<string>
>;
export const wrapper = createWrapper(initStore, {
debug: process.env.NODE_ENV === 'development',
});
I tried got solution about this problem but I don't found nothing really good. For hour I use this hack (this is shit, but works.).
import { rootReducer } from './modules/root';
const combinedReducer = combineReducers(rootReducer);
const reducer = (
state: ReturnType<typeof combinedReducer>,
action: AnyAction,
) => {
if (action.type === HYDRATE) {
const nextState = {
...state, // use previous state
...action.payload, // apply delta from hydration
};
return nextState;
} else {
return combinedReducer(state, action);
}
};
const makeStore = () =>
configureStore({
reducer: reducer as typeof combinedReducer,
});
type Store = ReturnType<typeof makeStore>;
export type RootState = ReturnType<Store['getState']>;
export type AppThunk<ReturnType = void> = ThunkAction<
ReturnType,
RootState,
unknown,
Action<string>
>;
export type AppDispatch = Store['dispatch'];
export const useAppDispatch: () => AppDispatch = useDispatch;
export const wrapper = createWrapper<Store>(makeStore, {
debug: process.env.NODE_ENV !== 'production',
});
If I found a better solution of that, I return here.