前端/移动开发面试题更新 2026-08-05

请说明 TypeScript 内置工具类型 Readonly 的用途及实现原理,并讨论其限制。

前端/移动开发技术原理方案权衡TypeScript

考察说明

考察对 TypeScript 内置工具类型 Readonly 的理解,包括其定义、实现及局限性。

回答思路

  1. 【回答框架 1】Readonly<T> 是 TypeScript 内置的实用类型,接受一个对象类型 T,返回一个所有属性均为只读的新类型,即新类型的每个属性都不能被重新赋值。其实现为 type Readonly<T> = { readonly [P in keyof T]: T[P] },通过映射类型遍历 T 的键,并添加 readonly 修饰符。
  2. 【回答框架 2】Readonly 只影响编译时的类型检查,不会修改对象在运行时的实际行为。对象属性仍可被修改,只是 TypeScript 编译器会阻止在类型层面上的赋值操作。
  3. 【回答框架 3】Readonly 是浅层的,它只会将 T 的顶层属性标记为只读,嵌套对象的属性不会被递归处理。例如,若 T 的属性值本身是对象,该对象的属性仍可变。若需要深度只读,需手动递归实现工具类型 DeepReadonly,例如 type DeepReadonly<T> = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K] }。
  4. 【回答框架 4】Readonly 与 Object.freeze 的区别在于前者是编译期类型约束,后者是运行时的 JavaScript 方法,会让对象属性变得不可写且不可删除,并返回同一对象。两者可以结合使用,但类型上的 readonly 不应被当作运行时保护。
  5. 【关键点 1】Readonly<T> 通过映射类型将 T 的所有属性加上 readonly,提供编译期属性不可重新赋值的类型约束。
  6. 【关键点 2】Readonly 是浅层的,嵌套对象属性不会被递归设为只读。
  7. 【关键点 3】Readonly 不影响运行时,属性实际仍可被修改。
  8. 【关键点 4】深层只读需自定义 DeepReadonly 工具类型。
  9. 【易错点 1】误认为 Readonly 会使对象在运行时不可修改。
  10. 【易错点 2】误以为 Readonly 会递归作用于嵌套属性。