不装库也能用的 ReadonlyDeep:把递归工具类型写一次
来源:dev.to — 2026-10-27
📋 概述
TypeScript 内置的 Readonly<T> 只作用于顶层属性,嵌套对象照样可改。把配置对象标成只读,队友在第三层改了个属性,编译器一声不吭,bug 到了生产才出现。递归的 ReadonlyDeep<T> 让每一层属性都不可变,而且没有运行时开销。实现要处理原始类型、函数、数组、Map、Set 和循环引用,靠条件类型按输入类型分支,对象那个分支对每个属性 K 递归成 ReadonlyDeep<T[K]>。type-fest 为边界情况增加了复杂度,一个聚焦版本三十行内够用。代价在编译性能:嵌套超过十层或属性上百个之后明显下降,大规模 schema 要先测再加。
🔑 核心要点
- 内置 Readonly 只管顶层,嵌套修改可以静默通过
- 递归类型在编译期拦下所有深度的修改,零运行时开销
- 条件类型要分别处理原始值、函数、数组、Map、Set 与循环引用
- 三十行内就能实现,但嵌套过深或属性过多会拖慢编译
💡 金句
“When a developer marks a configuration object as readonly and a teammate mutates a nested property three levels deep, the compiler stays silent.”
译:当有人把配置对象标成只读,而队友在第三层修改了嵌套属性时,编译器一声不吭。
← 返回 dev.to 首页