Persist-reducer 函数在打字稿中向我的减速器提供类型错误

Ali*_*aza 6 typescript reactjs redux react-redux redux-persist

我正在尝试在我的打字稿反应应用程序中配置反应持久。该persistReducer函数向我的减速器给出类型错误,类型为“(state: IState | undefined, action: Action) => IState”的参数不可分配给类型为“Reducer<unknown, Action>”的参数。这是我的store.ts代码。


const persistConfig = {
  key: "root",
  storage,
  stateReconciler: autoMergeLevel2,
  whiteList: ["reducer"],
};

const persistedReducer = persistReducer(persistConfig, reducer);//the type error

Run Code Online (Sandbox Code Playgroud)

这是我用于减速器的代码

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;
    }
    
}


Run Code Online (Sandbox Code Playgroud)


export interface IState{
    address:string,
    connection:boolean
    hourPassed:number
}

export const initialState:IState={
     address: '',
  connection: false,
  hourPassed:0
}

Run Code Online (Sandbox Code Playgroud)

行动

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
});


Run Code Online (Sandbox Code Playgroud)

如果Action我使用AnyAction(从 redux 导出),那么它工作正常,但我丢失了操作负载的类型声明。我在网上查看过但找不到任何解决方案。

Zis*_*han 11

在您的根减速器中,导出其类型:

import { combineReducers } from "@reduxjs/toolkit";

export const rootReducer = combineReducers({ ... });
export type RootReducer = ReturnType<typeof rootReducer>;
Run Code Online (Sandbox Code Playgroud)

然后将其导入到您的商店中并设置 persistReducer 如下:

import { rootReducer, RootReducer } from "./reducers";

const persistedReducer = persistReducer<RootReducer>(
  persistConfig,
  rootReducer
);
Run Code Online (Sandbox Code Playgroud)


小智 2

我在尝试将持久化器添加到我的根级别减速器时遇到了类似的问题。我花了一些时间才找到解决方案,因此请帮助引导人们找到此问题的解决方案: https: //github.com/rt2zz/redux-persist/issues/1140。为了保留类型声明,我必须将持久化器从根级别移到特定的减速器上。这是我使用工作类型声明实现的工作持久化器:

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
>;
Run Code Online (Sandbox Code Playgroud)

UiState 是初始 uiReducer 状态的接口。这就是为我的设置保留类型声明的原因。我留下了一些额外的东西来帮助查看完整的设置。