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

如何定义TypeScript泛型遍历路由配置树并累积路径?

TypeScript泛型实现路由结构到路径联合类型的深度转换

问题场景

给定以下路由类型与常量:

type Route = {
  path: string
  children?: readonly Route[]
}

const root = {
  path: "a",
  children: [
    { path: "b" },
    { path: "c", children: [{ path: "d", children: [{ path: "e" }] }] }
  ],
} as const satisfies Route;

需要实现泛型Convert<T extends Route>,将路由结构转换为所有完整路径的字符串联合类型,即Convert<typeof root>需输出'a' | 'a/b' | 'a/c' | 'a/c/d' | 'a/c/d/e'。

原实现代码仅能生成前三层路径,无法深度遍历嵌套层级:

type Convert<T extends Route, Prefix extends string = ''> = 
`${Prefix}/${T['path']}` | (
    T["children"] extends readonly Route[]
      ? {
        [K in number]: Convert<T['children'][K], `${Prefix}/${T['path']}`>;
      }[number]
      : never)

修正方案

调整泛型的递归逻辑与前缀初始值,确保深度遍历所有嵌套节点:

type Route = {
  path: string
  children?: readonly Route[]
}

const root = {
  path: "a",
  children: [
    { path: "b" },
    { path: "c", children: [{ path: "d", children: [{ path: "e" }] }] }
  ],
} as const satisfies Route;

type Convert<T extends Route, Prefix extends string = T['path']> = 
  // 先返回当前节点的完整路径
  Prefix | (
    // 提取子节点的类型并递归处理
    T["children"] extends readonly (infer C extends Route)[]
      ? {
        [K in keyof C]: Convert<C[K], `${Prefix}/${C[K]['path']}`>;
      }[number]
      : never
  )

// 验证结果:type Result = 'a' | 'a/b' | 'a/c' | 'a/c/d' | 'a/c/d/e'
type Result = Convert<typeof root>

关键调整说明

  1. 前缀初始值优化:将默认前缀设为T['path'],直接以当前节点的path作为初始路径,避免生成的路径开头出现多余斜杠。
  2. 递归逻辑完善:先返回当前节点的完整路径,再递归处理子节点。递归时将当前完整路径作为子节点的前缀,确保子节点的所有嵌套路径都能被逐层拼接并加入联合类型。
  3. 类型推断精准化:使用infer C extends Route提取子节点数组的元素类型,确保递归时类型传递的准确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 21:17:51