'Persist-reducer function giving type error to my reducer in typescript
I am trying to configure react-persist in my typescript react application. The persistReducer
function is giving a type error to my reducer that Argument of type '(state: IState | undefined, action: Action) => IState' is not assignable to parameter of type 'Reducer<unknown, Action>'. Here is my store.ts
code.
const persistConfig = {
key: "root",
storage,
stateReconciler: autoMergeLevel2,
whiteList: ["reducer"],
};
const persistedReducer = persistReducer(persistConfig, reducer);//the type error
This the code I am using for my reducers
export const reducer= (state:IState=initialState, action:Action):IState=> {
const {type, payload}=action;
switch(type){
case ActionType.CONNECT_META_MASK:
return {
...state,
address:payload.address,
connection:payload.connection
}
case ActionType.HOUR_PASSED:
return {
...state,
hourPassed:payload
}
default:
return state;
}
}
IState
export interface IState{
address:string,
connection:boolean
hourPassed:number
}
export const initialState:IState={
address: '',
connection: false,
hourPassed:0
}
Action
import {ActionType} from "../types/types"
interface IMetaMaskConnection{
type:typeof ActionType.CONNECT_META_MASK,
payload:{
connection:boolean,
address:string
}
}
interface IHourPassed{
type:typeof ActionType.HOUR_PASSED,
payload:number
}
export type Action = IMetaMaskConnection | IHourPassed
export const connectMetaMaskAction = (data:IMetaMaskConnection['payload']):Action => ({
type: ActionType.CONNECT_META_MASK,
payload:data
});
export const setHourPassed = (data:IHourPassed['payload']):Action => ({
type: ActionType.HOUR_PASSED,
payload:data
});
Instead of Action
if I use AnyAction
(exported from redux) then it works fine but I lose type declarations for my action payload.
I have looked online but I wasn't able to find any solution.
Solution 1:[1]
I had a similar issue while trying to add the persister to my root level reducer. And it took me some time to find a solution so help this directs people to the solution: https://github.com/rt2zz/redux-persist/issues/1140 for this issue. For me to keep type declarations I had to move the persister off of the root level and onto the specific reducer. Here is my implementation of the working persister with working type declarations:
import { configureStore, ThunkAction } from "@reduxjs/toolkit";
import { AnyAction, combineReducers } from "redux";
import thunk from "redux-thunk";
import storage from "redux-persist/lib/storage";
import autoMergeLevel2 from "redux-persist/lib/stateReconciler/autoMergeLevel2";
import persistReducer from "redux-persist/es/persistReducer";
import persistStore from "redux-persist/es/persistStore";
import uiReducer, { UiState } from "./reducers/uiReducer";
import apiReducer from "./reducers/apiReducer";
const persistConfig = {
key: "ui",
storage,
stateReconciler: autoMergeLevel2,
};
//Couldn't get state typings if persisting root reducer. Persisted by reducer works.
const reducers = combineReducers({
ui: persistReducer<UiState, any>(persistConfig, uiReducer),
api: apiReducer,
});
export const store = configureStore({
reducer: reducers,
middleware: [thunk],
});
export const persister = persistStore(store);
// Infer the `RootState` from the store itself to set up useAppDispatch and useAppSelector hook: https://react-redux.js.org/using-react-redux/usage-with-typescript
export type RootState = ReturnType<typeof store.getState>;
export type AppThunk<ReturnType = void> = ThunkAction<
ReturnType,
RootState,
unknown,
AnyAction
>;
UiState is the interface for the initial uiReducer state. This is what kept the type declarations for my setup. I left in some extra stuff to help see the full setup.
Solution 2:[2]
In your root reducer, export its type:
import { combineReducers } from "@reduxjs/toolkit";
export const rootReducer = combineReducers({ ... });
export type RootReducer = ReturnType<typeof rootReducer>;
Then import it into your store and set persistReducer as below:
import { rootReducer, RootReducer } from "./reducers";
const persistedReducer = persistReducer<RootReducer>(
persistConfig,
rootReducer
);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Colin Hale |
Solution 2 | Zishan Neno |