Immutable Record调用super()报错及Redux类型兼容问题求助
解决Immutable Record崩溃与Redux combineReducers类型错误问题
我来帮你一步步解决这两个问题,先从Immutable Record的运行时崩溃说起:
问题1:Immutable Record运行时崩溃(Error: Cannot set on an immutable record)
问题原因
Immutable的Record实例是不可变对象,你在constructor里直接给this.location赋值的操作,本质是在尝试修改这个不可变对象的属性,这就触发了Immutable的保护机制导致崩溃。而且实际上,当你调用super(props)或super()时,Record已经自动帮你初始化了location属性,完全不需要手动赋值。
修复后的代码
import { Record } from "immutable"; export enum officeLocations { cityOne = "CITYONE", cityTwo = "CITYTWO", none = "NONE", cityThree = "CITYTHREE", cityFour = "CITYFOUR" } export interface ILocationInfo { location: officeLocations; } const LocationInfoRecord = Record({ location: officeLocations.none }); export class LocationInfo extends LocationInfoRecord implements ILocationInfo { // TS可能会提示属性缺失,这里声明即可,不需要手动赋值 public location: officeLocations; constructor(props?: ILocationInfo) { // 简化构造逻辑:Record会自动处理props为undefined的情况,使用默认值 super(props); } public with(values: Partial<ILocationInfo>) { // 给merge结果加上类型断言,确保返回的是LocationInfo实例而非基础Record类型 return this.merge(values) as LocationInfo; } }
问题2:combineReducers类型不兼容错误
问题原因
Redux的reducer在初始化阶段会收到undefined作为state参数,但你的locationReducer当前只接受LocationInfo类型的参数,不兼容undefined,这就触发了TS类型检查错误。旧项目突然出现这个问题,大概率是TS配置变得更严格(比如开启了strictNullChecks),之前隐藏的类型问题现在暴露了。
修复方案
给reducer的state参数添加默认值,或者在reducer内部处理undefined的情况:
方案1:给state设置默认值
function locationReducer( location: LocationInfo = new LocationInfo(), action: IAction ): LocationInfo { // 你的reducer逻辑 switch (action.type) { case "SET_LOCATION": return location.with({ location: action.payload }); default: return location; } }
方案2:显式处理undefined情况
function locationReducer( location: LocationInfo | undefined, action: IAction ): LocationInfo { // 初始化时返回默认实例 if (location === undefined) { return new LocationInfo(); } // 你的reducer逻辑 switch (action.type) { case "SET_LOCATION": return location.with({ location: action.payload }); default: return location; } }
修改后,combineReducers就能正确识别reducer的类型了。
内容的提问来源于stack exchange,提问作者Fenopiù
相关产品推荐
相关产品推荐

