TypeScript封装可复用Reducer时store内reducer为never类型如何解决
问题原因
你自定义的createNamedWrapperReducer函数硬编码了固定的State、Action类型,且没有对齐Redux官方Reducer类型对初始state入参为undefined的兼容要求,导致combineReducers执行时类型推导失败,最终生成的reducer类型变为never。
修复方案
- 改造
createNamedWrapperReducer为泛型函数,动态适配不同业务reducer的类型:
import type { Reducer, Action } from 'redux'; // 扩展Action类型,增加name字段定义 interface NamedAction<T = any> extends Action<T> { name?: ReducerNames; } export function createNamedWrapperReducer<S, A extends NamedAction>( reducerFunction: Reducer<S, A>, reducerName: ReducerNames ): Reducer<S, A> { return (state: S | undefined, action: A) => { const { name } = action; const isInitializationCall = state === undefined; if (name !== reducerName && !isInitializationCall) return state as S; return reducerFunction(state, action); }; }
- 声明根State类型,显式传入
combineReducers避免类型推导异常:
import { combineReducers } from 'redux'; // 引入你各个业务模块的reducer import { reducer as userReducer } from './user/reducer'; import { reducer as orderReducer } from './order/reducer'; // 定义根State类型 export interface RootState { user: ReturnType<typeof userReducer>; order: ReturnType<typeof orderReducer>; // 其他模块的state类型依次补充 } // 显式传入RootState进行类型约束 const rootReducer = combineReducers<RootState>({ user: createNamedWrapperReducer(userReducer, 'user'), order: createNamedWrapperReducer(orderReducer, 'order'), // 其他模块的reducer依次补充 });
- 原有业务reducer代码无需做额外修改,改造完成后store的reducer类型即可正常推导。
内容的提问来源于stack exchange,提问作者KestVir
相关产品推荐
相关产品推荐

