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

TypeScript DeepOmit类型工具单属性可用,多属性失效问题求助

实现支持点语法与联合路径的DeepOmit类型工具

问题分析

你当前的DeepOmit实现仅能处理单个属性路径,当传入多个路径的联合类型时,由于TypeScript条件类型的分发特性,无法正确聚合所有路径的省略操作,导致结果不符合预期。

解决方案

核心思路是将联合路径拆分为单个路径逐个处理,再通过交叉类型合并所有省略结果,实现同时移除多个深层属性的效果。

完整实现代码

// 将联合类型转换为交叉类型,用于合并多次DeepOmit的结果
type UnionToIntersection<U> = 
  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

// 处理单个深层路径的省略逻辑
type DeepOmitSingle<T, Path extends string> = 
  T extends object 
    ? Path extends `${infer Key}.${infer Rest}`
      ? {
          // 遍历对象的每个键
          [K in keyof T]: K extends Key
            // 如果当前键匹配路径的第一部分,递归处理剩余路径
            ? DeepOmitSingle<T[K], Rest>
            // 不匹配则保留原类型
            : T[K]
        }
      // 路径无嵌套时,直接使用Omit移除顶层属性
      : Omit<T, Path>
    // 非对象类型直接返回原类型
    : T;

// 对外暴露的DeepOmit,支持单个或联合路径
type DeepOmit<T, Paths extends string> = 
  UnionToIntersection<
    Paths extends string ? DeepOmitSingle<T, Paths> : never
  >;

测试验证

type Input = {
  a: string;
  b: {
    c: string;
    d: string;
    e: string;
  };
};

// 测试单个路径
type OmitedSingle = DeepOmit<Input, "b.c">;
// 结果:{ a: string; b: { d: string; e: string } }

// 测试联合路径
type OmitedUnion = DeepOmit<Input, "b.c" | "b.d">;
// 结果:{ a: string; b: { e: string } }

实现说明

  1. UnionToIntersection:将联合类型转换为交叉类型,确保多个路径的省略操作是"同时生效"而非"二选一"。
  2. DeepOmitSingle:专注处理单个深层路径,通过模板字符串直接拆分路径的层级,递归处理嵌套对象,无需额外的数组转换逻辑,比原实现更简洁高效。
  3. DeepOmit:对传入的联合路径进行分发处理,每个路径单独执行DeepOmitSingle后,通过UnionToIntersection合并结果,最终得到所有路径都被省略后的类型。

原实现优化建议

  • 移除不必要的UnDot、Dot、Tail辅助类型,直接使用模板字符串拆分路径,减少类型计算的复杂度。
  • 利用联合转交叉的方式处理多路径场景,避免条件类型分发导致的逻辑错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 12:50:45