TypeScript 如何做只读属性

在写代码时,你有没有过这样的经历:某个变量本来只用来存一次固定信息,结果不小心被后续代码改乱了,排查bug花了大半天?其实TypeScript里藏着不少“防修改”的小工具,其中最常用的就是只读属性——它能帮你把需要固定的内容焊死,避免无心之失。

给对象属性加“只读锁”

日常写代码时,对象是最常用的数据载体,比如用它存用户的固定信息,像身份证号、出生日期这些一旦设好就不能改。TypeScript里给对象属性加只读,方法特别简单,只要在属性名前加readonly关键字就行。

TypeScript 如何做只读属性

举个生活化的例子:你用一个对象存自己的“法定信息”,idCard是身份证号,这辈子基本不变,name是姓名。这么写就能锁住不能改的内容:

`typescript

const userInfo = {

readonly idCard: "1101011990xxxx1234",

name: "张三"

};

`

这时候如果你想给userInfo.idCard重新赋值,比如userInfo.idCard = "110102",TypeScript会直接报错,就像给储物柜加了锁,别人拿不到里面的东西,你也没法私自换锁芯——这正好对应了只读属性的核心:编译阶段就拦截违规修改,而不是等代码跑起来才出问题。

不过要注意,这个只读只对“对象的直接属性”生效,要是属性本身是数组或对象,里面的内容还是能改。比如你存一个hobbies数组,就算给数组属性加了只读,还是能往里面加新爱好,因为数组的引用没被改,只是内部元素变了——就像你把储物柜本身锁了,但是柜门没锁,还是能往里面塞东西,得额外处理深层的只读。

用`readonly`修饰类里的属性

写面向对象代码时,类是另一个常用载体,比如用类定义学生,学号是入校时就定好的,之后不能改。类里的只读属性,也是用readonly修饰,而且可以在声明时直接赋值,或者在构造函数里初始化,不能在其他方法里修改。

举个学生类的例子:

`typescript

class Student {

// 声明时直接赋值的只读属性

readonly studentId: string = "2024001";

name: string;

constructor(name: string) {

this.name = name;

}

// 错误!不能在方法里修改只读属性

updateId() {

this.studentId = "2024002";

}

}

`

这里studentId是类的只读属性,不管是直接赋值还是构造函数里初始化,都没问题,但要是在updateId方法里改,TypeScript会提示错误,就像学生的学号一旦录入系统,老师也不能随便改,保证身份的唯一性。

深层只读:用`Readonly`泛型处理复杂结构

如果你的数据是嵌套的对象或数组,比如一个订单里包含商品列表,要求所有信息都不能改,这时候单个加readonly就不够用了,得用TypeScript自带的Readonly泛型。

Readonly能把整个类型的所有属性都变成只读,包括嵌套的内容,就像给整个大箱子加了锁,不管里面有多少小格子,都没法随便换东西。比如处理订单数据:

`typescript

interface Order {

orderId: string;

goods: {

name: string;

price: number;

}[];

}

// 把整个订单类型变成只读

const readonlyOrder: Readonly<Order> = {

orderId: "20240501001",

goods: [{ name: "笔记本", price: 5999 }]

};

// 错误!整个订单的属性都不能改

readonlyOrder.orderId = "20240501002";

// 错误!嵌套的商品信息也不能改

readonlyOrder.goods[0].price = 5499;

`

这样一来,不管是外层的订单号,还是内层的商品价格,都被锁住了,适合那些一旦生成就不能修改的固定数据,比如发票信息、合同条款。

其实TypeScript的只读属性,本质是在编译阶段做类型检查,帮你提前规避“不小心改了不该改的内容”的bug,不用等到代码运行后才抓错,是很实用的“代码安全防护”小技巧。

上一篇 JavaScript ReferenceError 怎么解决