从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"); // 正确提示两个参数
关键说明
- RouteParams类型优化:通过模板字符串递归匹配
/:param格式,直接从路由字符串中提取所有参数名,无需额外的RouteParser类型,逻辑更紧凑。 - 参数类型映射:使用
{ [K in RouteParams<Routes[T]>[number]]: string }将提取到的参数名映射为必填的string类型参数,让TypeScript能精准提示参数名和类型。 - 泛型约束:
T extends keyof Routes确保路由只能是预定义的routes对象中的值,避免传入任意字符串。
内容的提问来源于stack exchange,提问作者Matthieu Riegler
相关产品推荐
相关产品推荐

