You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带原始类型判断的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 05:18:20