typescript中定义只读属性和不可变数组主要用readonly关键字和as const断言:接口/类中用readonly修饰字段实现初始化后不可改;readonly string[]或readonlyarray声明只读数组,允许map/filter等操作但禁push/pop;as const用于字面量,推断出精确的只读字面量类型,且可冻结整个对象。

TypeScript 中定义只读属性和不可变数组,核心是控制“初始化后不可修改”这一行为,主要靠 readonly 关键字和 as const 断言两种方式,适用场景略有不同。
对象中定义只读属性
在接口、类型别名或类中,用 readonly 修饰字段,表示该属性只能在初始化时赋值,之后不可更改:
- 接口里声明:
interface User { readonly id: number; name: string; }
此时user.id = 100会报错,但user.name仍可改 - 类中使用:
class Config { readonly version = "1.0"; }
构造函数内或声明时赋值均可,但后续不能重新赋值 - 对象字面量直接加
readonly不生效,必须配合类型标注或as const
数组定义为不可变(只读数组)
有两种主流写法,语义和能力稍有区别:
-
readonly string[]或ReadonlyArray<string></string>:声明一个只读数组类型,允许调用map、filter等不修改原数组的方法,但禁止push、pop、索引赋值等变更操作 -
as const:适用于字面量数组,如const list = ["a", "b"] as const,推断出类型readonly ["a", "b"]—— 这不仅是只读,还精确到每个元素的字面量值,且长度固定 - 注意:
readonly string[]允许运行时动态生成(如从 API 获取),而as const只适用于编译期已知的字面量
批量让对象所有属性只读
不用逐个写 readonly,可用 as const 一键冻结整个对象字面量:
-
const config = { host: "api.example.com", port: 8080 } as const;
类型变为{ readonly host: "api.example.com"; readonly port: 8080 } - 此时
config.host = "new"直接报错,连属性名都成了字面量类型,可用于类型守卫或键值映射 - 适合配置项、枚举式数据、状态常量等明确不希望被修改的场景
只读数组的实际赋值限制
只读数组类型对赋值有方向性约束:
- 普通数组可以赋给只读数组变量:
let arr = ["x"]; let ro: readonly string[] = arr;✅ - 反过来不行:
arr = ro;❌ 编译错误,因为只读类型不能降级为可变类型 -
ReadonlyArray是纯类型,不能当构造函数用,比如new ReadonlyArray()会报错










