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

递归扁平化对象指定属性:移除sys、metadata并展开fields类型

解决TypeScript递归移除指定属性并扁平化fields的类型工具编写问题

需求说明

编写一个TypeScript类型工具,实现两个核心功能:

  • 递归移除对象中的sys、metadata属性
  • 将对象中的fields属性扁平化(即把fields内部的属性直接提升到当前层级)

输入类型

{
    sys: {
        id: string;
    };
    metadata: {
        author: string;
    };
    fields: {
        name: string;
        age: number;
        father: {
            sys: {
                id: string;
            };
            metadata: {
                author: string;
            };
            name: string;
        },
        siblings: {
            sys: {
                id: string;
            };
            metadata: {
                author: string;
            };
            name: string;
        }[]
    };
}

期望输出类型

{
    name: string;
    age: number;
    father: {
        name: string;
    };
    siblings: {
        name: string;
    }[];
}

当前思路瓶颈

原思路尝试通过映射类型判断键是否为sys/metadata来返回never,但无法正确处理fields的扁平化逻辑,也无法将扁平化后的属性与原对象(移除指定属性后)合并。现有代码片段:

type Helper<T extends object> = {
    [K in keyof T]: K extends "sys" | "metadata"
        ? never
        : K extends "fields"
        ? ...
        : T[K] extends Array<infer I>
        ? I extends object
            ? Helper<I>
            : never
        : T[K] extends object
        ? Helper<T[K]>
        : T[K];
};

解决方案

我们可以拆分逻辑为移除指定属性和扁平化+递归处理两个部分,通过组合多个辅助类型实现需求:

完整类型代码

// 移除对象中的sys和metadata属性
type RemoveSysMetadata<T> = Omit<T, "sys" | "metadata">;

// 递归处理扁平化fields和嵌套对象/数组
type FlattenFieldsAndRecurse<T> = T extends object
  ? T extends Array<infer U>
    ? // 处理数组:递归处理每个元素
      Array<FlattenFieldsAndRecurse<RemoveSysMetadata<U>>>
    : // 处理对象:先移除sys/metadata,再遍历键
      {
        [K in keyof RemoveSysMetadata<T>]: 
          // 若当前值是对象,先递归处理
          RemoveSysMetadata<T>[K] extends object
            ? FlattenFieldsAndRecurse<RemoveSysMetadata<T>[K]> extends infer ProcessedValue
              ? // 如果当前键是fields,直接返回处理后的值(扁平化)
                K extends "fields" ? ProcessedValue : ProcessedValue
              : never
            : // 非对象类型直接保留
              RemoveSysMetadata<T>[K];
      }
  : // 非对象类型直接返回
    T;

// 主类型工具
type CleanObject<T> = FlattenFieldsAndRecurse<T>;

代码解释

  1. RemoveSysMetadata:利用TypeScript内置的Omit类型,直接移除对象中的sys和metadata属性,比在映射类型中逐个判断更简洁高效。
  2. FlattenFieldsAndRecurse:
    • 首先判断输入是否为数组:如果是,递归处理数组中的每个元素(先移除sys/metadata,再递归)。
    • 如果是对象:先移除sys/metadata,然后遍历每个键值对:
      • 若值是对象,先递归处理该值;如果当前键是fields,则直接将递归处理后的值提升到当前层级(实现扁平化)。
      • 若值不是对象,直接保留原类型。
  3. CleanObject:对外暴露的主类型,调用上述辅助类型完成完整处理。

验证效果

// 定义输入类型
type InputType = {
    sys: { id: string };
    metadata: { author: string };
    fields: {
        name: string;
        age: number;
        father: {
            sys: { id: string };
            metadata: { author: string };
            name: string;
        },
        siblings: {
            sys: { id: string };
            metadata: { author: string };
            name: string;
        }[]
    };
};

// 生成处理后的类型
type OutputType = CleanObject<InputType>;

// 定义期望输出类型
type ExpectedOutput = {
    name: string;
    age: number;
    father: { name: string };
    siblings: { name: string }[];
};

// 验证类型是否匹配
type IsMatch = OutputType extends ExpectedOutput ? true : false; // 结果为true

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:46:37