TypeScript:readonly只读关键字

介绍

readonly 用于将 属性、数组 标记为 只读。一旦被赋值,就不能再被修改。

注意:不能修饰普通变量,否则报错

有助于提高代码的可读性、可维护性和安全性,尤其是在处理 不可变数据时。

标记只读属性 (类中)

这是最常见的用法。防止类的 属性 在实例化后被修改。

注意:只能在 声明时 或 构造函数中被赋值。

声明时赋值

class Mate80 {
  // 常量实例属性
  readonly cpu:string = "麒麟9900"

}

let lileiMate80 = new Mate80()

// 修改值报错
lileiMate80.cpu = "麒麟9800"

构造方法中赋值

class Mate80 {
  // 常量实例属性
  readonly cpu:string = "麒麟9900"

  constructor(cpu:string) {
    // 在构造方法中赋值
    this.cpu = cpu
  }
  modify(){
    // 在其他方法中不能赋值
    // this.cpu = "麒麟9800"
  }
}

let lileiMate80 = new Mate80("麒麟9999")

// 修改值报错
// lileiMate80.cpu = "麒麟9800"

标记接口中的只读属性

在接口中定义不可变的数据结构。

interface Point {
  readonly x: number;
  readonly y: number;
}

const origin: Point = { x: 0, y: 0 };
// origin.x = 5; // ❌ 错误!

标记只读数组(不在类中)

使用 readonly T[] 类型,创建一个 不可修改 的数组,但 可以重新赋值

let numbers: readonly number[] = [1, 2, 3];

// numbers.push(4); // ❌ 错误!没有 push 方法
// numbers[0] = 10; // ❌ 错误!不能通过索引修改
// numbers.length = 0; // ❌ 错误!不能修改 length

// ✅ 但可以读取
console.log("",numbers[0]); // 1
console.log("",numbers.length); // 3

可以重新赋值整个数组

numbers = [4, 5, 6];

函数参数是数组类型

防止在函数内部意外 修改传入的对象或数组,但 可以重新赋值

function processArray(arr: readonly string[]) {
  // arr.push("new"); // ❌ 错误!不能修改
  // arr = ["11","222"] // 可以重新赋值数组
  console.log(arr[0]);
}

const myArray = ["a", "b", "c"];
processArray(myArray); // ✅ 可以传入普通数组

readonly 与 const 对比

这是初学者常混淆的两个概念,它们的作用层级不同:

特性 readonly const
作用对象 属性 (对象的字段) 变量
修改 不能修改该属性的值 不能重新赋值
适用范围 类属性、接口属性、数组元素 变量声明
层级 更细粒度,控制对象内部 更粗粒度,控制变量引用

对比示例

// ✅ const 限制变量本身不能重新赋值
const person = { name: "Alice", age: 30 };
// person = { name: "Bob", age: 25 }; // ❌ 错误!不能改变 person 的指向

// ✅ 但可以修改 person 对象内部的属性(除非属性是 readonly)
person.age = 31; // ✅ 可以修改

// ✅ 结合使用:既不能改变变量,也不能改变属性
const readonlyPerson: { readonly name: string; readonly age: number } = {
  name: "Alice",
  age: 30,
};
// readonlyPerson.age = 31; // ❌ 错误!属性是 readonly
// readonlyPerson = { name: "Bob", age: 25 }; // ❌ 错误!变量是 const

readonly 与 private

可以组合使用,创建一个私有的、只读的属性。

class Secret {
  private readonly key: string;

  constructor(key: string) {
    this.key = key; // 只能在构造函数中赋值
  }

  // 其他方法可以读取 key,但不能修改
  getKeyHash(): string {
    return this.key + "-hashed";
  }
}

总结

  • readonly 是一个编译时检查,用于标记属性、数组或对象属性为只读。
  • 它不能阻止变量重新赋值(那是 const 的工作),而是阻止修改属性的值。
  • 与 const 结合使用,可以创建完全不可变的数据。

原文出处:/show_1GW21ts7dcpL.html