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

TypeScript路由构建函数无占位符时参数设为可选的实现方法

路由构建函数类型校验实现方案

功能要求

实现一个带类型校验的路由构建函数,满足以下规则:

  1. 仅支持传入预定义的合法路由
  2. 路由包含占位符时,必须传入键名、类型完全匹配的参数对象
  3. 路由无占位符时,不可传入参数

预期类型校验效果如下:

type Route = '/no-placeholders' | '/path/:p1/:p2'

buildUrl('/unknown-route') // 报错:路由不存在
buildUrl('/no-placeholders', {}) // 报错:无需传参却收到多余参数
buildUrl('/no-placeholders') // 校验通过
buildUrl('/path/:p1/:p2') // 报错:缺少必填参数
buildUrl('/path/:p1/:p2', { foo: '' }) // 报错:参数与路由占位符不匹配
buildUrl('/path/:p1/:p2', { p1: 'foo', p2: 'bar' }) // 校验通过

原有实现问题

初始实现尝试通过never类型重载处理无参场景,但未生效,代码如下:

type PathParams<Path extends string> = 
    Path extends `:${infer Param}/${infer Rest}` ? { [k in Param | keyof PathParams<Rest>]: string } :
    Path extends `:${infer Param}` ? { [k in Param]: string } :
    Path extends `${infer _Prefix}:${infer Rest}` ? { [k in keyof PathParams<`:${Rest}`>]: string } :
    never;

type Route = '/no-placeholders' | '/path/:p1/:p2'

function buildUrl<R extends Route>(route: R, params: never): string;
function buildUrl<R extends Route>(route: R, params: PathParams<R>): string;
function buildUrl(route: any, params: any) {
  // 路由参数替换逻辑省略
  return route
}

存在的问题:不管路由是否包含占位符,函数始终要求传入第二个参数,无参路由的可选参数规则未生效。

最终解决方案

通过函数重载分别处理有参、无参路由场景即可:

type PathParams<Path extends string> = 
    Path extends `:${infer Param}/${infer Rest}` ? { [k in Param | keyof PathParams<Rest>]: string } :
    Path extends `:${infer Param}` ? { [k in Param]: string } :
    Path extends `${infer _Prefix}:${infer Rest}` ? { [k in keyof PathParams<`:${Rest}`>]: string } :
    never;

// 拆分路由类型为无参、有参两类
type RouteWithoutParams = '/no-placeholders'
type RouteWithParams = '/path/:p1/:p2'
type Route = RouteWithoutParams | RouteWithParams

// 无参路由重载:仅需要传路由参数
function buildUrl<R extends RouteWithoutParams>(route: R): string;
// 有参路由重载:必须同时传入匹配的参数对象
function buildUrl<R extends Route>(route: R, params: PathParams<R>): string;
// 实现层将第二个参数设为可选,兼容两个重载分支
function buildUrl<R extends string>(route: R, params?: PathParams<R>) {
  // 路由参数替换逻辑省略
  return route
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 07:42:02