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

扁平化复杂Record时移除冗余交叉类型的技术问题

解决TypeScript Flattened类型中重复交叉类型的问题

问题描述

实现的Flattened类型在处理包含孤立键(如示例中的d)且该键值为联合类型的Record时,会生成大量重复的交叉类型项。比如输入:

{
  a: { b: ComplexA };
  c: { d: ComplexB };
  d: ComplexB;
}

期望生成的类型是:

{ a_b: ComplexA } & { c_d: ComplexB } & { d: ComplexB }

但实际生成的类型中,{ d: ComplexB }会重复出现多次(次数等于联合类型的成员数)。

问题原因

原代码中,处理孤立键的联合类型值时,{ [K in keyof T & string]: ... }[keyof T & string]会触发TypeScript的联合类型分发机制,对联合类型的每个成员单独生成一个{ d: 联合成员 }类型,之后UnionToIntersection将这些类型交叉合并,最终形成重复的{ d: ComplexB }项(虽然{d: B1} & {d: B2} & {d: B3}等价于{d: B1|B2|B3},但类型显示上会保留所有交叉项)。

修复后的代码

type Primitive = number | string | boolean | Date;

export type UnionToIntersection<U> =
  (U extends any ? (k: U) => void : never) extends (k: infer I) => void
    ? I
    : never;

export type Flattened<T, Sep extends string> = T extends
  | Primitive
  | unknown[]
  | Record<string, Primitive | unknown[]>
  ? T
  : T extends Record<string, unknown>
  ? UnionToIntersection<
      {
        [K in keyof T & string]: 
          type Flat = Flattened<T[K], Sep>;
          Flat extends Primitive | unknown[]
          ? { [P in K]: T[P] }
          : Flat extends Record<string, unknown>
          ? {
              [KFlat in keyof Flat & string as `${K}${Sep}${KFlat}`]: Flat[KFlat];
            }
          : { [KFlat in K]: Flat }
      }[keyof T & string]
    >
  : T;

type ComplexA = "complexA1" | "complexA2";
type ComplexB = "complexB1" | "complexB2" | "complexB3";

// 现在生成的类型符合预期:{a_b: ComplexA} & {c_d: ComplexB} & {d: ComplexB}
type Result = Flattened<
{
  a: { b: ComplexA };
  c: { d: ComplexB };
  d: ComplexB;
}, '_'
>

修复说明

核心修改点:

  • 将原代码中Flattened<T[K], Sep> extends infer Flat的条件推断改为直接声明type Flat = Flattened<T[K], Sep>,避免在条件判断中触发联合类型分发
  • 对于非Primitive/数组/Record的情况(即联合类型),直接生成包含整个联合类型的{ [KFlat in K]: Flat },不再对每个联合成员单独生成类型

这样就避免了联合类型分发导致的重复交叉项,生成的类型结构更简洁且符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:30:53