React+TypeScript中Redux createStore类型不匹配报错排查
解决React应用中Redux Reducer类型不匹配的编译错误
问题代码
store.ts
import { StoreReducer } from "./reducer"; import { StoreData, StoreAction } from "./types"; export const dataStore: Store<StoreData, StoreAction> = createStore(StoreReducer);
reducer.ts
import { ACTIONS, StoreData, StoreAction } from "./types"; import { Order } from "./entities"; import { Reducer } from "react"; //fn Reducer<S,A> where S is type that represents shape of the ds, //A is the type thar represents the actions the ds supports export const StoreReducer: Reducer<StoreData, StoreAction> = (data: StoreData | undefined , action) => { data = data || { products: [], order: new Order() } switch(action.type) { case ACTIONS.ADD_PRODUCTS: return { ...data, products: [...data.products, ...action.payload] }; case ACTIONS.MODIFY_ORDER: data.order.addProduct(action.payload.product, action.payload.quantity); return {...data}; case ACTIONS.RESERT_ORDER: return { ...data, order: new Order() } default: return data; } }
错误信息
TS2769: No overload matches this call ... Overload 1 of 2, '(reducer: Reducer<StoreData, StoreAction>, enhancer?: StoreEnhancer<Store<StoreData, StoreAction>, unknown> | undefined): Store<...>', gave the following error. Argument of type 'React.Reducer<import("reactapp/src/data/types").StoreData, import("reactapp/src/data/types").StoreAction>' is not assignable to parameter of type 'import("reactapp/node_modules/redux/index").Reducer<import("reactapp/src/data/types").StoreData, import("reactapp/src/data/types").StoreAction>'. Types of parameters 'prevState' and 'state' are incompatible. Type 'StoreData | undefined' is not assignable to type 'StoreData'. Type 'undefined' is not assignable to type 'StoreData'. Overload 2 of 2, '(reducer: Reducer<StoreData, StoreAction>, preloadedState?: { products: { id: number; name: string; description: string; category: string; price: number; }[]; order: { ...; }; } | undefined, enhancer?: StoreEnhancer<...> | undefined): Store<...>', gave the following error. Argument of type 'React.Reducer<import("reactapp/src/data/types").StoreData, import("reactapp/src/data/types").StoreAction>' is not assignable to parameter of type 'import("reactapp/node_modules/redux/index").Reducer<import("reactapp/src/data/types").StoreData, import("reactapp/src/data/types").StoreAction>'. 5 | 6 | //use Redux createStore method to create ds object > 7 | export const dataStore: Store<StoreData, StoreAction> = createStore(StoreReducer);
问题根源
你错误地从react包导入了Reducer类型,但实际是给Redux的createStore传Reducer。React的Reducer类型允许状态参数为undefined(适配useReducer初始化逻辑),而Redux的Reducer要求状态参数必须是明确的StoreData类型,不允许undefined,这直接导致类型不兼容报错。
修复方案
步骤1:修正Reducer类型的导入来源
将reducer.ts中的导入语句改为从redux获取Reducer类型:
import { Reducer } from "redux";
步骤2:调整Reducer函数的参数定义
Redux的Reducer第一个参数不需要undefined,可以给参数设置默认值来处理初始化逻辑:
export const StoreReducer: Reducer<StoreData, StoreAction> = (data: StoreData = { products: [], order: new Order() }, action) => { // 移除原有的`data = data || ...`语句,默认值已处理初始化 switch(action.type) { case ACTIONS.ADD_PRODUCTS: return { ...data, products: [...data.products, ...action.payload] }; case ACTIONS.MODIFY_ORDER: // 注意:Redux要求Reducer是纯函数,不能直接修改原状态对象 const updatedOrder = { ...data.order }; updatedOrder.addProduct(action.payload.product, action.payload.quantity); return { ...data, order: updatedOrder }; case ACTIONS.RESERT_ORDER: return { ...data, order: new Order() } default: return data; } }
额外优化:修正不纯操作
原代码中MODIFY_ORDER分支直接修改data.order,违反了Redux Reducer必须是纯函数的规则,会导致状态变更无法被正确追踪。上面的代码已改为创建新的Order对象并修改,保证了纯函数特性。
可选方案:在createStore时传入初始状态
如果你更倾向于在创建Store时指定初始状态,可按如下方式修改:
// store.ts const initialState: StoreData = { products: [], order: new Order() }; export const dataStore: Store<StoreData, StoreAction> = createStore(StoreReducer, initialState); // reducer.ts 无需给参数设置默认值 export const StoreReducer: Reducer<StoreData, StoreAction> = (data: StoreData, action) => { switch(action.type) { // ... 原有逻辑 } }
内容的提问来源于stack exchange,提问作者Mitch
相关产品推荐
相关产品推荐

