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

如何使用const断言从任意层级嵌套对象提取字面量类型?

从任意层级嵌套对象提取各层级字面量类型(TypeScript)

背景

之前处理过深度为2的嵌套对象结构,通过手动映射提取了各层级的字面量类型:

const grandkids = {
  Karen: {
    Ava: ['Alice', 'Amelia'],
    Emma: ['Sarah'],
  },
  Mary: {
    Sophia: ['Grace'],
  },
} as const;

对应的类型提取代码:

type Grandmother = keyof typeof grandkids; // Karen|Mary

type Mother = {
  [K in Grandmother]: keyof typeof grandkids[K];
}[Grandmother]; // Ava|Emma|Sophia

type Kid = {
  [K in Grandmother]: {
    [M in Mother]: typeof grandkids[K][M extends keyof typeof grandkids[K] ? M : never];
  };
}[Grandmother][Mother][number]; // Alice|Amelia|Sarah|Grace

问题延伸

当结构深度增加到3层时,手动映射的方式会变得繁琐且无法通用:

const greatgrandkids = {
  Beth: {
    Karen: {
      Ava: ['Alice', 'Amelia'],
      Emma: ['Sarah'],
    },
    Mary: {
      Sophia: ['Grace'],
    },
  },
  Ruth: {
    Ella: {
      Scarlett: ['Charlotte'],
    },
  },
} as const;

我们需要一种通用方式,提取任意层级的字面量类型:

type GreatGrandmother = /* 需要实现 */; // Beth|Ruth
type Grandmother = /* 需要实现 */; // Karen|Mary|Ella
type Mother = /* 需要实现 */;
type Kid = /* 需要实现 */;

通用解决方案

通过递归条件类型,可以实现任意层级的键提取和叶子元素类型提取:

1. 通用类型工具定义

// 提取对象的直接键类型
type Keys<T> = T extends object ? keyof T : never;

// 递归提取指定层级的所有键(Depth从0开始计数,对应最外层)
type NestedKeys<T, Depth extends number, CurrentDepth extends 0[] = []> = 
  CurrentDepth['length'] extends Depth 
    ? Keys<T> 
    : T extends object 
      ? NestedKeys<T[keyof T], Depth, [...CurrentDepth, 0]> 
      : never;

// 递归提取叶子节点的元素类型(支持数组或单个值叶子)
type LeafElement<T> = 
  T extends readonly (infer U)[] 
    ? U 
    : T extends object 
      ? LeafElement<T[keyof T]> 
      : T;

2. 实际使用示例

针对深度3的greatgrandkids对象:

// 第0层(最外层):曾祖母
type GreatGrandmother = NestedKeys<typeof greatgrandkids, 0>; // Beth|Ruth

// 第1层:祖母
type Grandmother = NestedKeys<typeof greatgrandkids, 1>; // Karen|Mary|Ella

// 第2层:母亲
type Mother = NestedKeys<typeof greatgrandkids, 2>; // Ava|Emma|Sophia|Scarlett

// 叶子元素:孩子
type Kid = LeafElement<typeof greatgrandkids>; // Alice|Amelia|Sarah|Grace|Charlotte

针对深度2的grandkids对象:

// 第0层:祖母
type Grandmother = NestedKeys<typeof grandkids, 0>; // Karen|Mary

// 第1层:母亲
type Mother = NestedKeys<typeof grandkids, 1>; // Ava|Emma|Sophia

// 叶子元素:孩子
type Kid = LeafElement<typeof grandkids>; // Alice|Amelia|Sarah|Grace

关键说明

  • 必须给嵌套对象添加as const断言,确保TypeScript保留所有字面量类型,而非推断为string等宽泛类型。
  • NestedKeys<T, Depth>通过递归遍历对象层级,直到达到指定深度后返回该层的所有键。
  • LeafElement<T>自动递归遍历到最底层,提取叶子节点的类型(支持数组或单个值场景)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 21:32:30