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

TypeScript如何定义单层扁平化对象的Flatten工具类型?

实现TypeScript单层扁平化工具类型Flatten

需求分析

我们需要实现一个工具类型Flatten,满足以下要求:

  • 接受两个泛型参数:目标对象类型T(结构为Record<string, Record<string, unknown>>)、顶层键的集合K(联合或元组类型,需包含所有顶层键)
  • 按K的顺序展开T中对应顶层键的对象属性,后续对象的同名属性会覆盖前面的
  • 仅扁平化顶层结构,深层嵌套对象保持原样

实现代码

// 合并两个对象类型,后续对象的属性覆盖前置对象的同名属性
type Merge<Prev extends Record<string, unknown>, Next extends Record<string, unknown>> = 
  Omit<Prev, keyof Next> & Next;

// 递归合并元组中的所有对象类型,按从左到右的顺序累积结果
type MergeTuple<
  T extends Record<string, Record<string, unknown>>,
  Keys extends readonly (keyof T)[],
  Acc extends Record<string, unknown> = {}
> = Keys extends [infer First extends keyof T, ...infer Rest extends (keyof T)[]]
  ? MergeTuple<T, Rest, Merge<Acc, T[First]>>
  : Acc;

// 将交叉类型转换为普通对象类型,优化类型显示效果
type ToObject<T> = { [P in keyof T]: T[P] };

// 辅助类型:将联合类型转换为元组(顺序由TypeScript类型系统决定)
type UnionToTuple<U> = (U extends any ? (x: U) => void : never) extends (x: infer T) => void ? T[] : never;

// 主工具类型Flatten
type Flatten<
  T extends Record<string, Record<string, unknown>>,
  K extends keyof T
> = 
  K extends readonly (keyof T)[]
    ? ToObject<MergeTuple<T, K>>
    : K extends keyof T
      ? ToObject<MergeTuple<T, UnionToTuple<K>>>
      : never;

代码说明

  1. Merge类型:

    • 使用Omit<Prev, keyof Next>移除前置对象中与后续对象重复的键,再与后续对象交叉,实现后续属性覆盖前置属性的效果,和Object.assign的行为一致。
  2. MergeTuple类型:

    • 通过递归遍历元组中的每个键,用Acc参数累积合并结果,严格按元组顺序从左到右合并,保证后续对象的属性能覆盖前面的。
  3. ToObject类型:

    • 把交叉类型转换为普通的对象字面量类型,避免结果显示为复杂的交叉表达式,提升可读性。
  4. UnionToTuple类型:

    • 将联合类型转换为元组,让联合类型也能复用MergeTuple的合并逻辑,虽然联合类型本身无序,但能保证所有顶层键对应的属性都被合并。

测试示例

定义示例类型:

type Example = {
  body: {
    user: {
      name: string;
      age: number;
    }
  },
  query: {
    id: string;
    strict?: boolean;
  },
  params: {
    id: number;
    scope: string[];
  }
};

调用Flatten<Example, 'query' | 'params' | 'body'>或Flatten<Example, ['query', 'params', 'body']>,都会得到目标类型:

{
  id: number;
  strict?: boolean;
  scope: string[];
  user: { name: string; age: number };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:25:56