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

TypeScript定义嵌套递归路由类型时VS Code报错如何解决?

问题原因

你遇到的类型报错根源出在RoutingVariants的索引签名定义上:

type RoutingVariants = {
  list: string,
  add: string,
  get: string,
  [key: string]: RoutingVariants | string, // 问题在这里
};

这个索引签名声明了所有字符串类型的key对应的值的类型是RoutingVariants | string联合类型,当你访问Routes.user.invoices的时候,TS无法确定这个值到底是字符串还是子路由对象,所以你继续访问.get属性的时候,TS会判定字符串类型上不存在get属性,因此抛出错误。

解决方案

推荐用类型推断+校验函数的写法,既能保留完整的自动补全能力,又能保证路由结构符合你的规则:

type GlobalRoutingT = 'user' | 'listing';

type RoutingVariants = {
  list: string;
  add: string;
  get: string;
  [key: string]: RoutingVariants | string;
};

// 路由定义校验函数,既约束结构符合要求,又保留你写的路由对象的精确类型
function defineRoutes<T extends Record<GlobalRoutingT, RoutingVariants>>(routes: T) {
  return routes;
}

export const Routes = defineRoutes({
  user: {
    list: '/user',
    add: '/user/add',
    get: '/user/:id',
    invoices: {
      list: '/user/invoices',
      add: '/user/invoices/add',
      get: '/user/invoices/:id',
    }
  },
  listing: {
    list: '/listing',
    add: '/listing/add',
    get: '/listing/:id',
  },
});

修改后你再访问Routes.user.invoices.get就不会有报错,TS会自动识别invoices是子路由对象类型,自动补全也完全正常。如果你写错了顶层路由key,或者某个路由节点缺少list/add/get属性,TS也会及时给出错误提示。

如果不想改结构,也可以用类型断言临时绕过报错,不推荐长期使用:

<Route path={(Routes.user.invoices as RoutingVariants).get} exact >
  <GetInvoice />
</Route>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:06:03