React/Redux创建Store时string类型无法分配给undefined类型报错的解决方案
问题根因
这个报错本质是TS类型推导偏差,并非运行时逻辑问题:
- 旧版Redux的TS类型定义对
combineReducers的返回值推导存在缺陷:如果组合reducer时没有显式标注类型,TS会错误把每个子reducer接收的state参数推导为undefined,最终导致createStore要求传入的预置State(preloadedState)被约束为「所有字段都是undefined」的类型,此时传入符合IAppState定义的初始值,就会触发Type 'string' is not assignable to type 'undefined'的校验错误。 - 你观察到的「reducer初始化阶段会收到undefined作为入参」是Redux设计层面的运行时逻辑,但类型层面Redux从未要求预置State必须为undefined,这个校验偏差是旧版类型定义的问题,不是业务代码的逻辑错误。
可落地的调整方案
按优先级逐步调整即可解决报错:
- 第一步:清理接口中的冗余类型定义,减少推导干扰
原IAppState中类似experiences: IGeneric[] | []的写法属于完全冗余的类型声明:空数组本身就是IGeneric[]的合法子集,额外叠加| []的联合类型会让TS在推导时生成多余的类型分叉,容易触发匹配异常。把所有这类冗余定义简化为数组本身的类型即可,调整后的接口示例:interface IAppState { currentSection: string; experiences: IGeneric[]; finishedScenario: boolean; formation: IGeneric[]; language: LanguageCode; languages: IGeneric[]; projects: IGeneric[]; skills: IGeneric[]; texts: IGeneric | Record<string, never>; textsDatabase: IGeneric | Record<string, never>; } - 第二步:修正Store和rootReducer的类型声明,覆盖错误的自动推导
不要依赖TS对类型的自动推导,显式给变量标注明确的类型:- 把原代码中无泛型的
let store: Store改为显式带状态类型的声明:let store: Store<IAppState> - 给
combineReducers组合完成的rootReducer显式标注Reducer<IAppState, AnyAction>类型,阻断TS的错误推导,示例代码:import { Reducer, AnyAction, combineReducers } from 'redux'; const rootReducer: Reducer<IAppState, AnyAction> = combineReducers({ currentSection: currentSectionReducer, experiences: experiencesReducer, finishedScenario: finishedScenarioReducer, formation: formationReducer, language: languageReducer, languages: languagesReducer, projects: projectsReducer, skills: skillsReducer, texts: textsReducer, textsDatabase: textsDatabaseReducer });
- 把原代码中无泛型的
- 第三步:如果报错仍未消除,手动指定createStore的泛型参数
createStore本身提供了完整的泛型重载能力,可以通过手动传参完全覆盖自动推导的结果,示例代码:
此时store = createStore< IAppState, AnyAction, ReturnType<typeof compose> >( rootReducer, INITIAL_STATE, compose(applyMiddleware(thunk, updateTexts), devToolsEnhancer()) );createStore的预置State参数会被明确约束为IAppState类型,不会再触发类型不匹配的校验错误。
内容的提问来源于stack exchange,提问作者Anya
相关产品推荐
相关产品推荐

