如何实现带原始类型判断的RecursiveReadonly<T>工具类型
实现递归的Readonly工具类型
常规的递归Readonly实现会将原始类型也进行包裹,导致出现RecursiveReadonly<boolean>这类不符合预期的类型,进而引发类型赋值错误。要解决这个问题,我们需要先判断类型是否为原始类型,仅对对象类型递归应用只读处理。
正确实现代码
// 定义所有JavaScript原始类型的联合类型 type Primitive = string | number | boolean | symbol | null | undefined | bigint; type RecursiveReadonly<T> = // 如果是原始类型,直接返回原类型,避免递归包裹 T extends Primitive ? T : // 如果是对象类型,对每个属性递归设置只读 T extends object ? { readonly [P in keyof T]: RecursiveReadonly<T[P]> } : T;
代码说明
- 原始类型判断:通过
Primitive联合类型覆盖所有JavaScript原始类型,当输入类型属于其中之一时,直接返回原类型,不再递归处理。 - 对象类型递归处理:对于对象类型(包括普通对象、数组、类实例等),遍历其所有属性并递归应用
RecursiveReadonly,确保嵌套层级的属性也被设置为只读。
测试示例
// 测试用的嵌套对象类型 type NestedObj = { isActive: boolean; details: { username: string; age: number; tags: string[]; }; }; // 生成递归只读类型 type ReadonlyNestedObj = RecursiveReadonly<NestedObj>;
生成的ReadonlyNestedObj类型自动推导结果如下:
type ReadonlyNestedObj = { readonly isActive: boolean; readonly details: { readonly username: string; readonly age: number; readonly tags: readonly string[]; }; };
可以看到,原始类型boolean、string、number都保持了原类型,没有被RecursiveReadonly包裹,完全符合类型兼容性要求。
内容的提问来源于stack exchange,提问作者PatrykB
相关产品推荐
相关产品推荐

