Readonly<T>

最后更新:2026-10-22

Readonly<T> Readonly

Readonly<T> 把 T 的所有属性变为只读:对象创建之后不允许再给属性赋值,编译器直接报错。适合配置对象、快照、共享常量这类"造出来就不该被改"的数据。注意它锁的是属性,和 const 锁的变量绑定是两回事。

分组工具类型
类型类型
严格模式不需要

ℹ️ 说明 编辑器将 TypeScript 转译为 JavaScript 后运行(不做类型检查);类型检查结果见示例 Output。

📝 语法

type Readonly<T> = {
  readonly [K in keyof T]: T[K];
};

// 用法
const config: Readonly<AppConfig> = { appName: "docs", port: 8080, debug: false };
// config.debug = true;  // 报错:无法分配到 debug,因为它是只读属性

⚙️ 参数

T被变换的对象类型;映射类型遍历其每个属性并加上 readonly 修饰符

返回值:一个新类型:属性集合与 T 相同,但全部带 readonly 标记。

▶ 示例

修改下面的代码,点击试一试查看转译运行结果:

输出:

docs-site:8080

(转译后运行输出;只读保护由 tsc 静态保证——放开注释那行会得到 error TS2540,运行时 JS 本身并不阻止赋值)

💡 要点

ℹ️ 说明 实现是映射类型:[K in keyof T] 加 readonly 前缀。转译后 readonly 完全消失,没有 Object.freeze 那样的运行时保护。
⚠️ 注意 Readonly 是浅层的:嵌套对象属性整体变只读,但嵌套对象内部的字段仍可修改;数组属性变成 ReadonlyArray,但数组元素如果是对象照样可改。深只读要自写 DeepReadonly。
💡 提示 与 as const 的区别:Readonly<T> 作用于已有类型(不改变字面量推断,mode 还是 string 类型值);as const 作用于字面量本身(mode 收窄成 "dark")。需要字面量收窄用 as const,只需要"防改"用 Readonly。
更多案例即将上线。

📚 相关教程

❓ 常见问题

Q Readonly 和 Object.freeze 有什么区别?
A Readonly 是纯编译期保护,转译后消失,运行时可改;Object.freeze 是运行时冻结,静默(或严格模式报错)阻止赋值。两者可以同时用:类型上 Readonly、运行时 freeze。
Q readonly 属性能通过 as 断言改掉吗?
A 可以绕过:(config as { debug: boolean }).debug = true 编译能过。这正说明 readonly 是编译期约定,不是运行时枷锁——绕过它等于主动放弃保护,团队代码里应禁止。
Q ReadonlyArray 和 readonly T[] 是什么关系?
A 完全等价:readonly T[] 是 ReadonlyArray<T> 的简写形式。两者都禁止 push/pop/修改下标,与 Readonly<T> 作用于对象属性同理,都是浅层只读。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏