面试题答案
一键面试实现代码
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object
? DeepPartial<T[P]>
: T[P];
};
实现过程中高级类型概念的运用
- 映射类型:
[P in keyof T]
这部分使用了映射类型。它会遍历类型T
的所有键P
,然后为每个键创建新的属性。这里通过[P in keyof T]?:
将属性设置为可选。 - 条件类型:
T[P] extends object? DeepPartial<T[P]> : T[P]
使用了条件类型。它判断T
中属性P
的类型T[P]
是否为对象类型。如果是对象类型,则递归应用DeepPartial
类型工具;如果不是对象类型,则保持原类型。 - 递归类型:在条件类型中,当
T[P]
是对象类型时,递归调用DeepPartial<T[P]>
,这使得嵌套对象的所有层级的属性都变为可选。
边界情况
- 循环引用:如果对象类型存在循环引用,例如
type Circular = { a: Circular }
,递归类型会导致无限循环,编译时会报错。实际应用中应避免创建这样的类型。 - 特殊类型处理:对于
Function
类型,在上述实现中它不会被当作对象类型递归处理,保持原类型。如果希望对函数类型的参数和返回值也进行类似处理,需要进一步扩展条件类型的判断逻辑。 - 泛型约束:若传入的
T
是一个受约束的泛型,例如T extends { requiredProp: string }
,在使用DeepPartial
后,requiredProp
依然会变为可选,可能与预期的部分属性保持必填有所冲突,需额外处理。