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

如何从树形IRoute结构推导所有路径的字符串联合类型?

问题

我定义了表示Web应用路由的TypeScript接口:

interface IRoute {
  readonly path: string;
  readonly children?: IRoute[];
}

给定该类型的示例对象:

const routes: IRoute = {
  path: '',
  children: [
    {
      path: '/dashboard',
    },
    {
      path: '/settings',
      children: [
        {
          path: '/notifications'
        },
        {
          path: '/profile',
          children: [
            {
              path: '/picture'
            },
          ]
        }
      ]
    }
  ]
};

我希望生成包含所有可能路径的联合类型,比如:

type AllRoutes = 
 | '/'
 | '/dashboard'
 | '/settings'
 | '/settings/notifications'
 | '/settings/profile'
 | '/settings/profile/picture'

请问是否可以从上述IRoute对象推导出这类全路径联合类型?


解决方案

可以实现,但首先需要调整routes的定义,让TypeScript保留其字面量类型信息(原定义中routes: IRoute会丢失具体的路径字符串和子路由结构细节)。

步骤1:保留路由对象的字面量类型

用as const断言锁定路由对象的字面量类型,避免TypeScript将其宽泛化为IRoute:

const routes = {
  path: '',
  children: [
    {
      path: '/dashboard',
    },
    {
      path: '/settings',
      children: [
        {
          path: '/notifications'
        },
        {
          path: '/profile',
          children: [
            {
              path: '/picture'
            },
          ]
        }
      ]
    }
  ]
} as const;

步骤2:编写递归类型工具拼接路径

定义两个递归条件类型,分别处理单条路由的路径生成和子路由的路径拼接:

// 处理单个路由及其子路由的完整路径生成
type BuildRoutePaths<T extends { path: string; children?: readonly any[] }> = 
  T['path'] extends '' 
    ? '/' | BuildChildPaths<T['children']>
    : T['path'] | BuildChildPaths<T['children'], T['path']>;

// 遍历子路由并拼接父路径
type BuildChildPaths<
  T extends readonly any[] | undefined,
  ParentPath extends string = ''
> = 
  T extends readonly (infer U)[]
    ? U extends { path: string; children?: readonly any[] }
      ? `${ParentPath}${U['path']}` | BuildChildPaths<U['children'], `${ParentPath}${U['path']}`>
      : never
    : never;

// 生成最终的全路径联合类型
type AllRoutes = BuildRoutePaths<typeof routes>;

验证结果

此时AllRoutes会被TypeScript自动推导为:

type AllRoutes = "/" | "/dashboard" | "/settings" | "/settings/notifications" | "/settings/profile" | "/settings/profile/picture"

核心逻辑是利用TypeScript的递归条件类型和模板字面量类型,结合as const保留的精确字面量信息,自动拼接出所有层级的完整路由路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:10:47