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

TypeScript递归获取类字段属性遇类型过深错误如何解决?

问题与解决方案

问题背景

尝试实现类的set方法,仅接受类的字段属性(排除函数、保留字段可选性),使用递归泛型处理嵌套结构时,触发Type instantiation is excessively deep and possibly infinite.错误,且不能通过// @ts-ignore忽略(会丢失类型安全)。

原代码问题分析

  1. 递归循环触发:Base类的set方法使用DeepWritable<typeof this>,子类Parent继承Base后,typeof this包含继承的set方法;同时Parent的arr字段是Parent[],递归处理时会反复带入包含set方法的类型,导致无限递归。
  2. 不必要的类型包含:DeepWritablePrimitive中错误包含了Function,与“排除函数”的需求冲突,且增加了递归复杂度。
  3. 键过滤逻辑冗余:原WritableKeys同时处理函数排除和只读属性判断,在递归场景下放大了类型计算压力。

修正后的代码

// 排除所有函数类型的键
type OmitFunctions<T> = {
  [K in keyof T as T[K] extends Function ? never : K]: T[K]
};

// 基础类型定义(排除Function)
type DeepWritablePrimitive = undefined | null | boolean | string | number;

// 带深度限制的递归泛型,避免无限递归
type DeepWritable<T, Depth extends number[] = []> = 
  Depth['length'] extends 10 ? T : // 限制最大递归深度为10,可按需调整
  T extends DeepWritablePrimitive ? T :
  T extends Array<infer U> ? Array<DeepWritable<U, [...Depth, 0]>> :
  T extends Map<infer K, infer V> ? Map<K, DeepWritable<V, [...Depth, 0]>> :
  T extends Set<infer U> ? Set<DeepWritable<U, [...Depth, 0]>> :
  // 先排除函数键,再递归处理字段
  {
    [K in keyof OmitFunctions<T>]: DeepWritable<OmitFunctions<T>[K], [...Depth, 0]>
  };

class Base {
  // 使用this类型,结合OmitFunctions排除自身方法,再做深度可写处理
  set(data?: Partial<DeepWritable<OmitFunctions<this>>>): void {
    Object.assign(this, data);
  }
}

class Parent extends Base {
  name?: string;
  arr?: Parent[];
};

const record = new Parent();
record.set({
  arr: [{
    name: '0'
  }]
});
console.log(record.arr);

关键改动说明

  1. 新增OmitFunctions<T>:直接过滤掉所有值为函数类型的键,逻辑简洁且避免递归时带入方法类型。
  2. 递归深度限制:通过Depth元组参数控制递归深度(默认10层),当达到指定深度时停止递归,避免类型计算溢出。
  3. 修正DeepWritable逻辑:
    • 移除DeepWritablePrimitive中的Function,明确基础类型范围。
    • 处理对象类型时,先通过OmitFunctions<T>排除函数键,再递归处理字段。
  4. set方法参数优化:使用OmitFunctions<this>替代typeof this,直接排除当前实例的所有方法,仅保留字段属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:44:54