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

升级Angular12/TypeScript4.3.5后对象属性赋值报只读错误

报错原因与解决方案

根因说明

你遇到的Cannot assign to read only property 'x' of object报错不是TypeScript 4.3的语法规则变更直接导致的,触发原因有两个核心点:

  1. Angular 12默认开启了严格模式,开发环境下会对输入属性(@Input)、状态管理返回的数据集做不可变校验,部分场景下会自动用Object.freeze冻结对象,禁止直接修改属性
  2. TypeScript 4.3增强了readonly修饰符的推断能力,如果你获取metrics数组的接口/方法返回的是带readonly标记的类型,编译期不会抛出显性错误,但运行期会触发Angular的不可变修改拦截

你之前的排查结论是正确的:循环中用const声明metric只会限制变量本身不能被重新赋值,不会限制内部成员修改;你定义的ScaMetricGraphType类的属性也没有被标记为只读,问题出在你拿到的metrics数组实例本身是不可变的。

可行解决方案

方案1:浅拷贝对象后修改(最推荐,符合不可变最佳实践)

不修改原数组的对象,通过浅拷贝生成新对象后赋值,后续用新生成的数组做业务逻辑:

const updatedMetrics = metrics.map(metric => ({
  ...metric,
  focalThemeSubArea: metric.focalThemeSubArea ?? metric.focalTheme
}))

方案2:类型断言绕开只读限制

如果你确认必须修改原对象,可以通过工具类型移除只读标记:

// 全局定义通用可变类型工具
type Mutable<T> = { -readonly [P in keyof T]: T[P] };

for (const metric of metrics as Mutable<ScaMetricGraphType>[]) {
  if (!metric.focalThemeSubArea) {
    metric.focalThemeSubArea = metric.focalTheme;
  }
}

如果你不想定义工具类型,也可以临时断言为any,但会丢失类型校验能力,不推荐。

方案3:关闭Angular严格模式校验(不推荐)

如果是开发模式的输入属性校验触发的报错,你可以在angular.json中关闭对应的严格校验规则,但会丢失类型安全收益,仅作为临时调试方案使用:

{
  "projects": {
    "你的项目名": {
      "architect": {
        "build": {
          "options": {
            "strictTemplates": false,
            "strictInputTypes": false
          }
        }
      }
    }
  }
}

内容的提问来源于stack exchange,提问作者FunkMonkey33

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 02:06:04