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

TypeScript如何消除never生成合法嵌套路径联合并实现类型安全查找

解法

1. 生成所有合法路径联合

你之前的尝试得到never是因为直接拼接两个无绑定关系的联合类型时,TS会将所有组合做交叉校验,不存在同时匹配foo的二级key和bar的二级key的组合,所以最终结果为never。

使用分布式条件类型遍历每个一级键,再拼接对应一级键下的所有二级键,即可得到合法路径的联合类型:

type Structure = {
  foo: {
    a: 1,
    b: 2,
  }
  bar: {
    c: 3,
    d: 4,
  }
}

// 通用的两层结构合法路径生成类型
type AllValid2LevelPaths<T extends Record<string, Record<string, any>>> = {
  [K in keyof T]: `${K & string}.${keyof T[K] & string}`
}[keyof T]

// 得到的类型就是 "foo.a" | "foo.b" | "bar.c" | "bar.d"
type StructurePath = AllValid2LevelPaths<Structure>

此时你可以直接使用路径联合做类型声明,不需要传泛型参数:

const path: StructurePath = 'foo.a' // 合法
const invalidPath: StructurePath = 'foo.c' // 类型报错

2. 实现类型安全的lookup函数

通过模板字面量类型拆分路径,再通过索引访问匹配对应值的类型即可:

// 通用的两层结构路径取值类型
type Get2LevelPathValue<T, P extends string> = 
  P extends `${infer K extends keyof T & string}.${infer S extends keyof T[K] & string}` 
    ? T[K][S] 
    : never

// 运行时函数实现(可根据你的实际取值逻辑调整)
const structure: Structure = {
  foo: { a: 1, b: 2 },
  bar: { c: 3, d: 4 }
}
function lookup<P extends StructurePath>(path: P): Get2LevelPathValue<Structure, P> {
  const [branch, section] = path.split('.') as [keyof Structure, keyof Structure[keyof Structure]]
  return structure[branch][section] as any
}

// 测试效果
const x = lookup("foo.a") // x类型自动推断为字面量 1
const y = lookup("bar.d") // y类型自动推断为字面量 4
lookup("foo.c") // 直接抛出类型错误,路径不合法

如果后续你需要支持更深层级的路径,可以把上面的两个工具类型改成递归实现即可适配任意深度的结构。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 21:12:03