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

如何将组件定义的类型继承到react-router-dom的路由跳转方法中?

最优解决方案

核心思路是统一维护路由与传参类型的映射关系,扩展 React Router 内置类型实现跳转时的自动类型校验,避免两端类型声明不一致的问题。

步骤1:抽离公共路由类型定义

新建单独的路由类型文件(比如 src/types/routes.ts),统一管理所有路由的路径与对应接收的 state 类型:

// src/types/routes.ts
// 目标页接收的state类型,统一在这里定义避免重复声明
export interface SomeStuffProps {
  stuff: string;
  moreStuff: string;
}

// 全局路由映射:key为路由路径,value为该路由接收的state类型
export interface RouteStateMap {
  "/display": SomeStuffProps;
  // 其余有传参需求的路由可以在此追加
  // "/detail": { id: number; name: string }
  [key: string]: unknown;
}

步骤2:扩展React Router内置类型

针对使用 v5 版本 useHistory 的场景

新增类型声明文件扩展 history 包的 History 类型,让 push/replace 方法自动匹配传入路径对应的 state 类型:

// src/types/react-router.d.ts
import { RouteStateMap } from "./routes";
import { History } from "history";

declare module "history" {
  export interface History<S = unknown> {
    push<P extends keyof RouteStateMap>(
      path: P,
      state?: RouteStateMap[P]
    ): void;
    replace<P extends keyof RouteStateMap>(
      path: P,
      state?: RouteStateMap[P]
    ): void;
  }
}

针对使用 v6 版本 useNavigate 的场景

扩展 react-router 包的 NavigateFunction 类型即可,逻辑与v5一致:

// src/types/react-router.d.ts
import { RouteStateMap } from "./routes";
import { NavigateFunction } from "react-router";

declare module "react-router" {
  export interface NavigateFunction {
    <P extends keyof RouteStateMap>(
      to: P,
      options?: { state?: RouteStateMap[P]; replace?: boolean }
    ): void;
  }
}

步骤3:业务侧使用

跳转页调用逻辑

不需要手动声明state类型,TS会自动根据传入的路径校验state格式:

// /new-post 页面代码
import { useHistory } from "react-router-dom"; // v5版本
//  v6版本导入 import { useNavigate } from "react-router-dom"

const history = useHistory();
// 传入"/display"时自动校验state是否符合SomeStuffProps要求
history.push("/display", {
  stuff: "内容1",
  moreStuff: "内容2"
});

// 类型错误时会直接触发编译报错,提前发现问题
// history.push("/display", { stuff: 123 }) // 会提示stuff类型不匹配

目标页取值逻辑

直接从全局路由映射中取对应路径的state类型,不需要重复导入单独的Props类型:

// /display 页面代码
import { useLocation } from "react-router-dom";
import { RouteStateMap } from "@/types/routes";

// state自动获得SomeStuffProps类型
const location = useLocation<RouteStateMap["/display"]>();
const { stuff, moreStuff } = location.state;

方案优势

  • 所有路由传参类型统一维护,修改时只需调整一处,两端自动同步
  • 跳转时自动校验类型,避免手动声明类型的人为错误
  • 不需要在跳转页重复引入目标组件的Props类型,耦合度更低

如果项目规模很小不想做全局类型扩展,也可以选择把state类型抽离为公共类型,两端直接引用同一个类型定义,虽然没有路径与类型的自动绑定校验,也能避免两端类型定义不一致的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 06:06:04