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

TypeScript:如何将含Nested泛型的嵌套类型平展为父级类型?

如何实现将Nested泛型类型平展并保持键值对应?

给定包含Nested<T>泛型的类型,需要实现FlatNested<T>类型,将Nested<T>内部的内容平展到父类型中,使平展后的类型能正确关联键与对应的值,而非将所有值合并为联合类型。

问题重现

现有代码实现的FlatNested会将嵌套类型的值变为联合类型,无法匹配对应键:

type Nested<T> = T & { _: string } // 确保Nested<T>与T不相等

type Example = { a: string, b: string, n: Nested<{ n1: 'n1-val', n2: 'n2-val' }> }

type FlatNested<T> = { 
  [K in keyof T as T[K] extends Nested<infer N> ? keyof N : K]: 
    T[K] extends Nested<infer N> ? T[K][keyof N] : T[K] 
};

type t1 = FlatNested<Example>
// 当前结果:{a: string;b: string;n1: "n1-val" | "n2-val";n2: "n1-val" | "n2-val";}
// 期望结果:{a: string;b: string;n1: "n1-val" ;n2: "n2-val";}

问题原因

原实现中,T[K][keyof N]会取N所有值的联合类型——因为keyof N是N所有键的联合,所以每个平展后的键都会拿到所有嵌套值的集合,而非对应键的具体值。

解决方案

将逻辑拆分为两部分:保留非嵌套属性、平展嵌套属性并关联对应键值,最后通过交叉类型合并结果:

type Nested<T> = T & { _: string }

type Example = { a: string, b: string, n: Nested<{ n1: 'n1-val', n2: 'n2-val' }> }

// 提取并保留所有非Nested类型的属性
type NonNestedProps<T> = {
  [K in keyof T as T[K] extends Nested<any> ? never : K]: T[K]
}

// 提取Nested类型内部的属性,并映射到对应的值
type FlattenNestedProps<T> = {
  [K in keyof T as T[K] extends Nested<infer N> ? keyof N : never]: 
    T[K] extends Nested<infer N> ? N[K] : never
}

// 合并非嵌套属性与平展后的嵌套属性
type FlatNested<T> = NonNestedProps<T> & FlattenNestedProps<T>

// 验证结果
type t1 = FlatNested<Example>
// 结果等价于:{a: string; b: string; n1: "n1-val"; n2: "n2-val";}

代码解释

  • NonNestedProps<T>:遍历T的所有键,过滤掉类型为Nested<any>的属性,保留原本的非嵌套属性。
  • FlattenNestedProps<T>:遍历T的所有键,当遇到Nested<infer N>类型时,将N的键作为新键,并直接取N[K]作为对应值——这里K是N的键,因此能精准关联到对应的值。
  • 交叉类型&将两部分属性合并,得到最终的平展类型。

如果需要支持多层嵌套的平展,可以将FlatNested改为递归实现:

type FlatNestedRecursive<T> = 
  T extends Nested<infer N> 
    ? FlatNestedRecursive<N> 
    : {
        [K in keyof T]: 
          T[K] extends Nested<infer N> 
            ? FlatNestedRecursive<N> 
            : T[K]
      }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 11:22:02