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

TypeScript中如何更新类对象属性?遇对象不可扩展错误

问题解决:无法修改对象属性,提示"object is not extensible"

问题场景

现有类定义consumption.ts:

export class ConsumptionDetails {
  Id: string;
  Status: string;
  Description: string;
  Quantity: number;
}

在组件的Function 1中订阅数据:

this.lineItems$.subscribe((result: BindingState<ConsumptionDetails>) => {
  if(result){
    this.tempObj = result;
  }
});

在Function 2中尝试修改属性时报错:

this.tempObj.Status = 'Submitted';
console.log(this.tempObj);

错误信息:

ERROR TypeError: Cannot add property Status, object is not extensible

原因分析

BindingState<ConsumptionDetails>返回的对象是不可扩展/被冻结的,这类对象通常由状态管理库(如NgRx)或框架内部处理生成,目的是保证数据不可变,避免意外修改原始状态。这类对象通过Object.preventExtensions()、Object.seal()或Object.freeze()被限制了扩展能力,直接修改属性会触发报错。

解决方案

1. 浅拷贝生成可扩展对象

在Function 1中,将返回的结果浅拷贝到新对象中,新对象默认是可扩展的:

this.lineItems$.subscribe((result: BindingState<ConsumptionDetails>) => {
  if(result){
    // 使用对象展开运算符浅拷贝
    this.tempObj = {...result};
    // 或者用Object.assign实现
    // this.tempObj = Object.assign({}, result);
  }
});

之后再执行this.tempObj.Status = 'Submitted'就可以正常修改属性了。

2. 转换为类实例(如果需要保留类的结构)

如果需要tempObj是ConsumptionDetails的实例,可以用Object.assign将结果赋值给类的新实例:

this.lineItems$.subscribe((result: BindingState<ConsumptionDetails>) => {
  if(result){
    this.tempObj = Object.assign(new ConsumptionDetails(), result);
  }
});

3. 深拷贝(针对有嵌套属性的场景)

如果result包含嵌套对象,浅拷贝无法处理嵌套层级的不可扩展问题,这时可以用深拷贝:

this.lineItems$.subscribe((result: BindingState<ConsumptionDetails>) => {
  if(result){
    // 用JSON序列化/反序列化实现深拷贝(注意:会丢失函数、Symbol等特殊类型)
    this.tempObj = JSON.parse(JSON.stringify(result));
    // 或者使用lodash的cloneDeep(需先安装lodash)
    // import { cloneDeep } from 'lodash';
    // this.tempObj = cloneDeep(result);
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:55:06