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

TypeScript 4.7.4中嵌套键工具类型抛出TS2589错误如何解决?

解决TypeScript 4.7+中NestedKeyOf类型实例化过深的问题

你编写的NestedKeyOf工具类型用于提取对象的嵌套键路径,在TypeScript 4.3.5中能正常运行,但到了4.7.4版本会触发TS2589: Type instantiation is excessively deep and possibly infinite错误。这是因为TypeScript 4.7+对递归条件类型的检测变得更严格,默认递归深度限制被收紧,深层嵌套对象的类型推导会触发溢出。

解决方案:添加递归深度限制

通过引入可选的深度控制参数,结合辅助类型实现递归层数限制,同时利用TypeScript的条件类型延迟实例化特性绕过过深检测。修改后的代码如下:

type NestedKeyOf<ObjectType extends Record<string, unknown>, Depth extends number = 10> = 
  Depth extends 0 ? never : {
    [Key in keyof ObjectType & (string | number)]: 
      ObjectType[Key] extends Record<string, unknown>
        ? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key], Decrement<Depth>>}`
        : `${Key}`
  }[keyof ObjectType & (string | number)];

// 辅助类型:实现数字类型减1
type Decrement<N extends number> = 
  N extends 1 ? 0 : 
  N extends 2 ? 1 : 
  N extends 3 ? 2 : 
  N extends 4 ? 3 : 
  N extends 5 ? 4 : 
  N extends 6 ? 5 : 
  N extends 7 ? 6 : 
  N extends 8 ? 7 : 
  N extends 9 ? 8 : 
  N extends 10 ? 9 : 
  number;

关键优化点:

  • 深度限制参数:新增Depth参数(默认值设为10),递归到指定深度时停止,返回never终止递归。你可以根据实际业务中对象的嵌套层数调整这个默认值。
  • Decrement辅助类型:实现数字类型的减1操作,每递归一层就将深度减1,直到触发终止条件。
  • 延迟实例化:用对象映射类型包裹递归逻辑,让TypeScript在需要时才实例化嵌套类型,而非提前展开所有递归层级,避免触发过深检测。

备选方案:固定层数展开

如果你的业务场景中对象嵌套层数固定且不深,也可以直接展开固定层数的递归,这种方式更简单但灵活性较差:

type NestedKeyOf<T extends Record<string, unknown>> = 
  | keyof T & (string | number)
  | `${keyof T & (string | number)}.${keyof T[keyof T] & (string | number)}`
  | `${keyof T & (string | number)}.${keyof T[keyof T] & (string | number)}.${keyof T[keyof T][keyof T[keyof T]] & (string | number)}`;

修改后的类型在TypeScript 4.7.4及更高版本中可正常编译,同时保留原有的嵌套键提取功能。

内容的提问来源于stack exchange,提问作者JIyHaTuK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:39:17