题目描述 🎯
实现一个通用的DeeepReadonly<T>类型,他将对象的每个参数及其子对象递归的设置为只读。
题目分析 📝
type X = {
x: {
a: number
b: string
}
y: string
}
type Expercted = {
readonly x: {
readonly a: number
readonly b: string
}
readonly y: string
}
需要考虑的问题:
- 处理对象的每个属性。
- 递归处理嵌套对象。
- 为每层级的属性添加
readonly修饰符。
解题思路 💡
- 使用映射类型遍历对象的所有属性。
- 为每个属性添加
readonly修饰符。 - 对属性值进行判断:
- 如果是对象类型,递归应用
DeepReadonly。 - 如果是基本类型,直接使用原类型。
代码实现 ⌨️
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P]
}
题解详解 🔍
- 映射类型部分
[P in keyof T]
- 遍历对象
T的所有属性。
readonly修饰符
readonly [P in keyof T]
- 为每个属性添加
readonly修饰符。
- 条件类型判断
T[P] extends object ? DeepReadonly<T[P]> : T[P]
- 如果属性值是对象,递归应用
DeepReadonly。 - 如果不是对象,保持原类型。
示例分析 🌟
interface Example {
name: string;
info: {
age: number;
address: {
city: string;
}
}
}
type Result = DeepReadonly<Example>;
// 执行过程:
// 第一层
{
readonly name: string; // 基本类型,直接加 readonly
readonly info: { // 对象类型,递归处理
readonly age: number;
readonly address: { // 继续递归处理
readonly city: string;
}
}
}
// 详细步骤:
// 1. 处理name属性,name 是 string 类型,直接添加 readonly 修饰符。
readonly name: string;
// 2. 处理 info 属性,info 是一个对象类型,递归处理。
readonly info: DeepReadonly<{
age: number;
address: {
city: string;
}
}>
// 3. 递归处理 info 内部
readonly info: {
readonly age: number; // age 是基本类型
readonly address: DeepReadonly<{
city: string;
}>
}
// 最终结果
readonly name: string;
readonly info: {
readonly age: number;
readonly address: {
readonly city: string;
}
}