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

TypeScript中readonly与ReadonlyArray处理数组的差异及选型疑问

TypeScript中readonly修饰符与ReadonlyArray的差异解析

先看示例代码:

class ReadonlyArrsClass {
  readonly arr: string[] = ['1', '2'];
  arr2: ReadonlyArray<string> = ['1', '2'];

  addToArr(): void {
    this.arr.push('333'); // 正常执行
  }

  addToArr2(): void {
    this.arr2.push('444'); // 报错:类型'readonly string[]'上不存在属性'push'
  }

  changeArrData(): void {
    this.arr = ['555']; // 报错:无法赋值给'arr',因为它是只读属性
  }
  changeArr2Data(): void {
    this.arr2 = ['666']; // 正常执行
  }

   logToConsole(): void {
    console.log(this.arr);
    console.log(this.arr2);
  }

  constructor(){
    this.addToArr();
    this.addToArr2();
    this.logToConsole();
    this.changeArrData();
    this.changeArr2Data();
    this.logToConsole();
  }
}

new ReadonlyArrsClass;

疑问

  1. 为何用readonly修饰的arr可以通过push()添加元素,而ReadonlyArray类型的arr2却不行?
  2. 为何ReadonlyArray类型的arr2可以重新赋值引用,而readonly修饰的arr却不能?

差异原因解析

问题1:添加元素的差异

  • readonly arr: string[] 里的readonly是属性修饰符,它只限制属性本身的引用不能被重新赋值,但属性指向的数组对象是普通可变数组(string[]),支持push、pop等修改内部元素的方法,所以可以调用push修改数组内容。
  • arr2: ReadonlyArray<string> 里的ReadonlyArray是只读数组类型,它的定义直接屏蔽了所有会修改数组内容的方法(比如push、splice),只保留读取类方法(比如slice、map),所以无法修改数组内部元素。

问题2:重新赋值的差异

  • readonly修饰的核心作用就是禁止对属性进行引用重新赋值,不管属性指向的是什么类型,都不能用this.arr = 新值的方式改变它的引用。
  • ReadonlyArray<string>只是限定了变量的类型为只读数组,但没有限制变量本身的引用可变性。只要新赋值的内容符合ReadonlyArray<string>类型(比如普通数组可以兼容赋值),就可以给arr2重新赋值。

推荐用法

  • 若需要属性引用不可变,但允许修改数组内部元素:使用readonly arr: string[]。
  • 若需要数组内部元素不可修改,但允许属性引用被重新赋值:使用arr2: ReadonlyArray<string>(或更简洁的readonly string[]语法)。
  • 若需要既禁止属性引用重新赋值,又禁止修改数组内部元素:结合两者写成readonly arr3: ReadonlyArray<string>或readonly arr3: readonly string[]。

这类特性能在编译阶段约束数据的可变性,避免意外修改,提升代码健壮性,在团队协作或复杂项目中建议根据实际需求合理使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 00:26:13