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

TypeScript递归属性路径拼接无法生成预期联合类型求助

问题原因与解决办法:TypeScript双层嵌套对象路径联合类型返回never

问题原因

你的FirstIteration类型逻辑存在核心问题:当你使用Obj[keyof Obj]时,得到的是所有子对象类型的联合类型(比如typeof ONE_SIMPLE | typeof TWO_SIMPLE | typeof HELLO_SIMPLE | typeof FALSE_SIMPLE)。而keyof作用在联合类型上时,只有当所有成员类型都拥有完全相同的键时,才会返回这些共同键;如果成员键不重合,keyof会直接返回never。这里每个子对象的键都不重复,导致SecondIteration接收的keyof Obj[keyof Obj]是never,最终整个FirstIteration返回never。

解决办法

要解决这个问题,需要使用分布式条件类型,遍历根对象的每个键,单独处理每个键对应的子对象,再拼接路径。修改FirstIteration的定义即可:

interface UnknownRecord {
  [key: string]: unknown;
}

type SecondIteration<Prefix extends string, Obj extends UnknownRecord> =
  keyof Obj extends string ?
    `${Prefix}.${keyof Obj}` :
    never;

interface DoubleUnknown {
  [name: string]: UnknownRecord;
}

// 修改后的FirstIteration:通过分布式条件类型逐个处理每个根键
type FirstIteration<Obj extends DoubleUnknown> =
  keyof Obj extends infer K ?
    K extends string ?
      SecondIteration<K, Obj[K]> :
      never :
    never;

// 测试代码
const ONE_SIMPLE: { nr1a: number; nr2b: number; } = { nr1a: 1, nr2b: 1 };
const TWO_SIMPLE: { nr2a: number; nr2b: number; } = { nr2a: 2, nr2b: 2 };
const HELLO_SIMPLE: { str1: string } = { str1: 'hello' };
const FALSE_SIMPLE: { bln: boolean } = { bln: false };

const inputs = { ONE_SIMPLE, TWO_SIMPLE, HELLO_SIMPLE, FALSE_SIMPLE };

const firstExample: SecondIteration<'test', typeof ONE_SIMPLE> = 'test.nr2b';
// 现在类型会正确推导为所有合法路径的联合类型
const secondExample: FirstIteration<typeof inputs> = 'ONE_SIMPLE.nr1a';

原理说明

分布式条件类型会自动将联合类型K(即keyof Obj的所有键)拆分为单个成员,对每个K单独执行SecondIteration<K, Obj[K]>,最后将所有结果合并为一个联合类型。这样就避免了直接处理子对象联合类型的问题,确保每个子对象的键都能被正确提取并拼接路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 03:42:05