开发者问题收集

Typescript、ReduxJS Toolkit - createSlice 生成的 Reducer 不能分配给类型为“Reducer<unknown, AnyAction>”的参数

2021-01-07
8332

我是 TypeScript 新手,在理解错误方面存在问题。我尝试使用由 @reduxjs/toolkit 的 createSlice 生成的 Reducer,并将其输入到具有以下定义的函数中:

// .d.ts file
export default function persistReducer<S, A extends Action = Action>(
  config: PersistConfig<S>,
  baseReducer: Reducer<S, A>
): Reducer<S & PersistPartial, A>;

// function definition
export default function persistReducer<State: Object, Action: Object>(
  config: PersistConfig,
  baseReducer: (State, Action) => State
): (State, Action) => State & PersistPartial { /* ... */

它返回以下错误:

Argument of type 'Reducer<CoreState, AnyAction>' is not assignable to parameter of type 'Reducer<unknown, AnyAction>'.
  Types of parameters 'state' and 'state' are incompatible.
    Type 'unknown' is not assignable to type 'CoreState | undefined'.
      Type 'unknown' is not assignable to type 'CoreState'.ts(2345)

但是,当我将 Reducer 转换为 redux/toolkit 提供的 Reducer 类型时,它可以工作。

// fails
persistReducer( persistConfig, coreReducer )

// succeeds
persistReducer( persistConfig, coreReducer as Reducer)

据我所知,Reducer 已经有这种类型,我不确定为什么我需要在发送之前转换值。我遗漏了什么?任何帮助都将不胜感激!

这是我的切片定义

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

export type User = {
  id: string,
  name: string,
  avatar: string,
  token: string
}

export type CoreState {
  isSignedIn: boolean,
  user: User | null
};

const defaultCoreState : CoreState = {
  isSignedIn: false,
  user: null
};

export const slice = createSlice({
  name: 'core',
  initialState: defaultCoreState,
  reducers: {
    setUser: (state: CoreState, action: PayloadAction<User | null>) => {
      state.user = action.payload;
      state.isSignedIn = action.payload ? true : false;
    }
  }
});

export const { setUser } = slice.actions;
export default slice.reducer;

编辑:使用 combineReducers 创建的 Reducer 会触发相同的错误,并且可以通过相同的解决方法缓解。在我看来, persistReducer 函数在推断类型时遇到了麻烦,即使它从同一个库导入了相同的 Reducer 类型定义。怎么回事?

2个回答

感谢 Reactiflux discord 上 @phryneas 的慷慨帮助,问题已解决。

export default function persistReducer<S, A extends Action = Action>

应改为:

export default function persistReducer<S, A extends AnyAction>

在调试此问题时,我梳理了所有定义,多次看到“Action”和“Any”这两个词,因此我忽略了它们之间的区别。 AnyAction 是正确的类型。

technosis
2021-01-08

如果您想升级项目,但不想重写所有内容,这是一个可使用的黑客。我使用的是:

218668986

我在节点模块中没有修复 persistreducer

我尝试使用旧风格的redux时遇到了这个问题带Redux工具包的还原器。

Asif Amin
2023-06-18