摘要

本 RFC 提出一种类型化路由参数的机制,用于前端开发中路由跳转的参数传递。通过自动推断和类型化目标页面的路由参数,减少手动维护文档和跳转表的复杂性,提高开发效率和代码可靠性。该提案借鉴 “Typed Router” 的概念,实现参数的静态类型检查和提示,适用于复杂的前端项目,尤其是涉及跨组协作的场景。

问题描述

当前现状

在前端开发中,页面间路由跳转常常涉及复杂的参数传递。随着项目规模增长,页面数量增多,参数变得臃肿且难以管理。这些参数包括业务配置(如stageId、subjectId)、UI选项(如hideNavigation、orientation)以及来源信息(如fromPageName)。参数的作用各异,但大多数默认必选,缺失会导致功能异常。

示例

以下是典型的参数传递代码示例,展示了复杂性和潜在问题:

browserJump({
  hideNavigation: true,
  orientation: 'horizontal',
  ...config,
  business: {
    stageId: stageId || undefined,
    subjectId: subjectId || undefined,
    semesterId: semesterId || undefined,
    publisherId: publisherId || undefined,
    courseType: type,
    fromPageName: '搜索',
    from: 'search',
    sessionId: getQueryObject().sessionId,
    ...config?.business,
  },
})

在该示例中,参数通过对象扩展合并,此时基本上所有的类型都失效了,容易引入未定义值或类型不匹配,导致运行时错误。

挑战

  • 复杂度增加:跨组协作时,跳转到其他页面的参数需求不可控,容易引发 bug。

  • 文档维护问题:依赖 README.md 或技术方案文档记录参数,但更新不及时、维护负担重。常见问题包括:维护位置不统一、更新责任不明、文档同步延迟。

  • 手动跳转表:人为维护跳转函数或表会导致开发体验差、bug 频发。若更新滞后,可能造成 P0 级生产事故。

  • 示例场景:从“搜索”功能跳转到多种页面(如“新中考总复习”、“小学物理专项课”、“初中英语重难点培优”),或扩展到习题搜索(如“专项突破”、“字谜游戏”、“快背地理”),参数差异大,难以统一管理。

提案概述

核心概念

本提案引入 “类型化路由参数” 机制,让路由系统 “自动嗅探” 目标页面的参数需求,并提供类型化提示。开发者在调用跳转时,IDE 可实时显示所需参数、类型和默认值,避免手动文档查询。

实现机制

  • 使用 TypeScript 接口定义每个页面的路由参数。

  • 通过路由注册系统,自动生成类型安全的跳转函数。

  • 支持参数验证、默认值填充和运行时检查。

详细规范

类型化路由参数定义

每个页面如果有参数需要获取,则必须按规范在项目根目录定义好 TypeScript 接口,例如起名为 pages-params.ts,用于描述其路由参数。

例如(新中考总复习项目):

export interface BasePageParams {
  // ... 定义了客户端会传入到前端的参数,例如 appVersion、phoneModel 等客户端通用参数
}
​
export interface NewTotalReviewBusiness extends BasePageParams {
  url: '/totalReviewLandscape/newTotalReview'
  menuId?: string
  chapterId: string
  specialCourseId: string
  sectionId: string
  subsectionId: string
}
​
export interface OldTotalReviewBusiness extends BasePageParams {
  url: '/totalReviewLandscape/oldTotalReview'
  chapterId: string
  sectionId: string
  subsectionId: string
  courseId: string
  courseType: string
  topicId: string
  specialCourseId: string
}

在该项目中,当在项目、项目组件中使用 getQueryObject 时,要求传入当前页面地址作为泛型,以获取精准的类型定义。

image-20250926180904947

跳转示意

自动嗅探和提示

创建 unplugin-typed-query 插件,与 Webpack、Vite 等构建工具集成,实现扫描 App 下 pages-params.ts,根据 getQueryObject 使用到的泛型地址,实现生成 typed-query.d.ts。

例如:

image-20250926182056315

优势和益处

  • 向前兼容:现有非类型化跳转可以继续使用,但需要逐步迁移。

  • 提高效率:自动提示减少文档查询时间。

  • 减少 bug:类型检查捕获运行时错误。

  • 简化协作:跨组开发时,无需手动维护跳转表。

  • 可维护性:参数定义与代码同在,更新即时。

  • AI 友好:当使用 AI 进行 Agent 开发的时候可以允许 AI 开发功能跳转的业务。

致谢

@huangqian 为实现机制部分带来灵感。

@shangzhiyu 给予了肯定促成此 RFC 的诞生。