Redux更新后出现TS2322错误:参数'action'类型不兼容排查
Redux更新后TS类型错误的根本原因分析
遇到的错误
TS2322: Type '(state: ILanguage | undefined, action: PayloadAction<ILanguage>) => ILanguage' is not assignable to type 'Reducer<ILanguage, AnyAction>'. Types of parameters 'action' and 'action' are incompatible. Property 'payload' is missing in type 'AnyAction' but required in type '{ payload: ILanguage; type: string; }'. > 63 | language: LanguageReducer, | ^^^^^^^^ 64 | }, 65 | });
我的代码片段
Reducer代码
import { PayloadAction } from "@reduxjs/toolkit"; type ILanguage = { isEnglish: boolean; }; const initialState: ILanguage = { isEnglish: true, }; export const reducer = (state: ILanguage = initialState, action: PayloadAction<ILanguage>): ILanguage => { switch (action.type) { case LanguageActionType.SET_LANGUAGE: { const isEnglish = action?.payload?.isEnglish || true; return { ...state, isEnglish, }; } case LanguageActionType.RESET_STATE: { return { ...initialState }; } default: return state; } };
Action代码
import { PayloadAction } from "@reduxjs/toolkit"; export const actionCreators = { resetState: () => ({ type: LanguageActionType.RESET_STATE, }), setLanguage: (isEnglish: boolean) : PayloadAction<ILanguage> => ({ payload: { isEnglish }, type: LanguageActionType.SET_LANGUAGE, }), };
临时解决方法(但想知道根本原因)
我可以给action参数加上| AnyAction来抑制错误:
export const reducer = (state: ILanguage = initialState, action: PayloadAction<ILanguage> | AnyAction): ILanguage => {
根本原因分析
Redux的Reducer类型约束:Redux要求Reducer必须符合
Reducer<State, AnyAction>类型,意味着你的reducer得能处理任意类型的Action——包括不带payload的Action。但你现在把reducer的action参数限定为PayloadAction<ILanguage>,这个类型强制要求所有Action必须带payload属性,直接和Redux的类型约定冲突。实际Action存在无payload的情况:你的
resetStateaction creator返回的Action没有payload字段,但reducer却要求所有Action都必须符合PayloadAction<ILanguage>的结构,这就造成了类型不匹配。版本更新后的严格检查:Redux(尤其是Redux Toolkit)的类型定义在更新后变得更严格,之前可能允许这种宽松的类型匹配,现在则明确抛出类型错误。
更优的解决方法(替代加AnyAction)
别用AnyAction掩盖问题,给reducer的action参数定义所有可能的Action类型联合,既能满足Redux的类型要求,又能保留TypeScript的类型检查优势:
- 先定义所有Language相关的Action类型:
import { actionCreators } from './你的action文件路径'; type LanguageAction = | ReturnType<typeof actionCreators.resetState> | ReturnType<typeof actionCreators.setLanguage>;
- 修改reducer的action参数类型:
export const reducer = (state: ILanguage = initialState, action: LanguageAction): ILanguage => { // 原有逻辑保持不变 };
这样TypeScript会自动推导每个case分支的Action类型,比如在RESET_STATE分支里,它知道这个Action没有payload;在SET_LANGUAGE分支里则明确知道有payload属性,类型检查更精准。
内容的提问来源于stack exchange,提问作者Sachihiro
相关产品推荐
相关产品推荐

