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

如何通过点符号排除对象键,实现TypeScript递归泛型转换

实现ValueOrStringExcludeNestedKeys<T, K>泛型类型

需求是实现一个TypeScript泛型,递归地为对象的所有基本类型属性(包括嵌套子属性)添加string联合类型,但需排除K中以点符号指定的路径集合对应的属性,这些排除的属性保留原有类型不变。

示例场景

type Values = {
  a: {
    b: {
      c: string;
      d: number;
    };
    e: string;
  };
  f: number;
  g: number;
  h: {
    i: number;
  }
};

type Result = ValueOrStringExcludeNestedKeys<Values, 'a.b.c' | 'f'>;
/* 期望结果:
type Result = {
    a: {
        b: {
            c: string; // 保持原类型不变
            d: number | string;
        };
        e: string; // string | string 等价于 string
    };
    f: number; // 保持原类型不变
    g: number | string;
    h: {
        i: number | string;
    };
} */

实现思路

要完成这个泛型,核心是处理路径匹配和递归遍历对象结构:

  1. 拆分点分隔的路径字符串为层级元组,方便逐层匹配嵌套属性
  2. 递归遍历对象的每个属性,判断当前属性的路径是否属于排除列表
  3. 对基本类型属性,若不在排除路径则添加string联合类型;对象类型则继续递归处理

完整代码实现

// 辅助类型:将点分隔的路径字符串拆分为元组
type SplitPath<S extends string> = S extends `${infer Head}.${infer Tail}` 
  ? [Head, ...SplitPath<Tail>] 
  : [S];

// 核心泛型实现
type ValueOrStringExcludeNestedKeys<T, K extends string, CurrentPath extends string[] = []> = 
  T extends object 
    ? {
        [Key in keyof T]: 
          // 拼接当前路径,判断是否在排除列表中
          `${[...CurrentPath, Key extends string ? Key : never].join('.')}` extends K 
            ? T[Key] // 路径匹配,保留原类型
            : ValueOrStringExcludeNestedKeys<T[Key], K, [...CurrentPath, Key extends string ? Key : never]>
      }
    : // 基本类型,若不在排除路径则添加string联合类型
      `${CurrentPath.join('.')}` extends K 
        ? T 
        : T | string;

代码解释

  1. SplitPath:递归拆分路径字符串,比如SplitPath<'a.b.c'>会得到['a','b','c'],用于后续层级匹配(内部逻辑支撑路径拼接判断)。
  2. ValueOrStringExcludeNestedKeys:
    • 若当前类型是对象,遍历每个属性,拼接当前路径后判断是否属于排除路径:是则保留原类型,否则递归处理子属性
    • 若当前是基本类型,判断当前路径是否在排除列表:是则保留原类型,否则返回原类型 | string

测试验证

用示例中的Values类型测试:

type TestResult = ValueOrStringExcludeNestedKeys<Values, 'a.b.c' | 'f'>;
// 输出结果与预期完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:15:24