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

如何不使用字符串索引将两层深度对象值转为TypeScript联合类型?

问题原因

你之前使用的typeof obj[keyof typeof obj]写法,只会提取对象第一层属性的值类型,对当前示例来说,拿到的是两个子对象的联合类型:

type FirstLevel = {
  readonly aa: "A";
  readonly cc: "C";
} | {
  readonly bb: "B";
  readonly cc: "C";
}

TypeScript对联合类型做直接索引取值时,只会返回所有联合成员共有的属性对应的类型,两个子对象只有cc是公共属性,所以最终只会得到"C",无法拿到各自独有的"A"和"B"。

实现方案

不需要硬编码任何字符串索引,写一个递归的通用深度取值类型即可适配任意嵌套结构的常量对象:

// 深度提取嵌套对象所有底层值的联合类型
type DeepValueOf<T> = T extends Record<string, unknown>
  ? DeepValueOf<T[keyof T]>
  : T;

// 传入对象类型直接得到结果
type ObjValue = DeepValueOf<typeof obj>;
// 验证结果:type ObjValue = "A" | "B" | "C"

类型逻辑说明:

  • 先判断当前传入的类型是不是对象,如果是对象,就遍历它所有键对应的值,递归传入DeepValueOf继续下一层处理
  • 条件类型遇到联合类型时会自动分发处理每个成员,不会出现之前只取公共属性的问题
  • 递归到非对象类型(也就是最底层的字面量值)时直接返回,所有返回的字面量会自动合并为联合类型
  • 因为你的对象已经加了as const断言,所有值都会保留精确的字面量类型,不会被拓宽为通用string类型,最终结果和预期完全一致。

如果你的对象里存在非字符串类型的值,只想提取字符串字面量的联合,可以给终止条件加一层字符串判断:

type DeepStringValueOf<T> = T extends Record<string, unknown>
  ? DeepStringValueOf<T[keyof T]>
  : T extends string ? T : never;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:36:38