求助:我的type-challenges 9.Deep Readonly解法为何无法通过全部用例?
问题分析与解决方案
你的DeepReadonly实现无法通过全部测试用例,核心问题有两个:
1. 错误处理函数类型
你用T[K] extends Object判断是否需要递归,但Object类型在TypeScript中包含了函数类型。当对象属性是函数时,递归处理会生成readonly {}(因为keyof Function返回never),这与测试用例中函数保持原有类型的预期不符。
2. 数组处理不符合预期
数组属于Object的子类型,原代码会遍历数组的所有键(包括数字索引和length、push等内置方法),将它们全部标记为readonly。但正确的深度只读数组应该是数组本身只读,且每个元素都被深度只读处理,而非修改数组内置方法的只读性。
正确实现方案
type DeepReadonly<T> = { readonly [K in keyof T]: // 函数类型直接返回,不做只读处理 T[K] extends (...args: any[]) => any ? T[K] // 数组转为只读数组,元素深度只读 : T[K] extends any[] ? readonly DeepReadonly<T[K][number]>[] // 普通对象递归处理深度只读 : T[K] extends object ? DeepReadonly<T[K]> // 原始类型直接返回 : T[K] }
逻辑说明:
- 优先判断函数类型:直接返回原函数,避免不必要的递归。
- 处理数组类型:将数组转为
readonly数组,同时对数组的每个元素应用DeepReadonly,实现深度只读。 - 普通对象:递归遍历所有属性,标记为
readonly并处理嵌套对象。 - 原始类型(string/number/boolean等):直接返回,无需处理。
内容的提问来源于stack exchange,提问作者风雪心
相关产品推荐
相关产品推荐

