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

从Angular路由字符串提取参数并作为函数参数传入

提取Angular路由参数并实现类型提示

需求背景

现有如下Angular路由定义:

const routes = {
  foo: '/foo/:paramFoo',
  bar: '/bar/:paramFoo/:paramBar',
  baz: '/baz/baz2/:paramFoo/:paramBar',
} as const;

希望实现routing函数,根据传入的路由自动提示所需参数:

  • 调用routing(routes.foo)时,提示参数为(route: "/foo/:paramFoo", paramFoo: string)
  • 调用routing(routes.bar)时,提示参数为(route: "/bar/:paramFoo/:paramBar", paramFoo: string, paramBar: string)

当前问题

已写出初步代码,但未实现预期的类型提示效果,同时希望将RouteParser的逻辑整合到RouteParams类型中。

解决方案

直接整合路由参数解析逻辑到RouteParams类型中,调整泛型约束实现正确的类型推导:

const routes = {
  foo: '/foo/:paramFoo',
  bar: '/bar/:paramFoo/:paramBar',
  baz: '/baz/baz2/:paramFoo/:paramBar',
} as const;

type Routes = typeof routes;

// 整合解析逻辑的RouteParams类型:从路由字符串中提取所有参数名
type RouteParams<S extends string> = 
  string extends S ? string[] :
  S extends `${string}/:${infer Param}/${infer Rest}` ? [Param, ...RouteParams<`/:${Rest}`>] :
  S extends `${string}/:${infer Param}` ? [Param] :
  [];

// 实现带类型提示的routing函数
function routing<T extends keyof Routes>(
  route: Routes[T],
  ...params: { [K in RouteParams<Routes[T]>[number]]: string }
) {
  // 示例实现:拼接路由与参数
  let resolvedRoute = route;
  params.forEach((param, index) => {
    const paramKey = RouteParams<Routes[T]>[index];
    resolvedRoute = resolvedRoute.replace(`:${paramKey}`, param);
  });
  return resolvedRoute;
}

// 测试验证
routing(routes.foo, "testFoo"); // 正确提示必填paramFoo参数
routing(routes.bar, "fooVal", "barVal"); // 正确提示paramFoo、paramBar参数
routing(routes.baz, "fooVal", "barVal"); // 正确提示两个参数

关键说明

  1. RouteParams类型优化:通过模板字符串递归匹配/:param格式,直接从路由字符串中提取所有参数名,无需额外的RouteParser类型,逻辑更紧凑。
  2. 参数类型映射:使用{ [K in RouteParams<Routes[T]>[number]]: string }将提取到的参数名映射为必填的string类型参数,让TypeScript能精准提示参数名和类型。
  3. 泛型约束:T extends keyof Routes确保路由只能是预定义的routes对象中的值,避免传入任意字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:39:20