如何实现TypeScript接口的精准可变转换:仅移除readonly修饰符
实现递归移除所有readonly修饰符的TypeScript工具类型
你的问题核心是原Mutable类型的判断逻辑太宽泛,导致对基本类型也进行了不必要的递归。我们可以通过更精准的类型分支判断来解决这个问题:
type Mutable<T> = { -readonly [K in keyof T]: T[K] extends readonly (infer U)[] ? U[] : T[K] extends object ? Mutable<T[K]> : T[K]; };
逻辑说明:
- 移除对象属性的readonly:通过
-readonly [K in keyof T]直接移除当前对象所有属性上的readonly修饰符,比如原接口中的readonly field_c会被转为普通属性。 - 处理readonly数组:优先判断属性是否为
readonly数组类型,通过infer提取数组元素类型U,将其转为普通数组U[],完美解决readonly string[]转string[]的需求。 - 递归处理嵌套对象:如果属性是对象类型(且已经排除了数组),则递归应用
Mutable类型,处理嵌套结构中的readonly。 - 保留基本类型:对于基本类型(如
number、null、string)直接返回原类型,避免不必要的递归。
测试验证
用你的Example接口测试:
interface Example { field_a: number | null; field_b: readonly string[]; readonly field_c: string; nested: { field_d: readonly unknown[] } } type TransformedExample = Mutable<Example>;
最终TransformedExample的类型完全符合你的预期:
{ field_a: number | null; field_b: string[]; field_c: string; nested: { field_d: unknown[]; }; }
这个工具类型可以动态适配任意结构的接口,无论是单层属性、嵌套对象还是readonly数组都能正确处理。
内容的提问来源于stack exchange,提问作者PMN
相关产品推荐
相关产品推荐

