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

TypeScript如何表示由不可变对象构成的不可变数组以满足不可修改契约?

TypeScript 类中实现数组及内部对象全不可修改的方案

报错原因

你遇到的ts(4104)错误本质是类型可变性不匹配:Readonly<Array<T>>(等价写法为readonly T[]或ReadonlyArray<T>)是只读数组类型,没有push/pop/splice等修改数组的方法,也不允许直接修改数组下标对应的元素,可变性约束比普通Array<T>更严格,因此只读数组类型的值不允许赋值给可变数组类型的变量,避免后续出现意外修改。

最优解决方案

直接将类的bars属性也声明为只读数组类型,完全符合你要求的「数组本身+内部所有对象都不可修改」的契约,修改后代码如下:

export type Foo = { foo: string };

export class Bar {
  // 声明为Readonly<Foo>可保证foo对象的内部属性也不可修改
  readonly foo: Readonly<Foo>;
  // 此处将可变数组类型改为只读数组类型,两种写法等价:
  // readonly Readonly<Bar>[]  / ReadonlyArray<Readonly<Bar>>
  readonly bars: readonly Readonly<Bar>[];

  constructor(
    foo: Readonly<Foo>,
    bars: readonly Readonly<Bar>[],
  ) {
    this.foo = foo;
    this.bars = bars;
  }
}

该方案的约束效果:

  • 无法修改Bar实例的foo属性,也无法修改foo内部的foo字段
  • 无法修改Bar实例的bars数组本身(不能增删元素、不能替换指定下标的元素)
  • 无法修改bars数组内部存储的任意Bar实例的属性

不推荐的绕过方案

如果特殊场景下需要绕过类型检查,可以在赋值时添加类型断言,但该方案会破坏不可修改的约束,可能导致后续意外修改数组,仅做了解不推荐使用:

this.bars = bars as Readonly<Bar>[];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 14:15:04