You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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ù

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:27:57