【奇淫技巧】让你的路由跳转拥有TS类型提示,告别人工记路由path

背景

在前端开发中,每次执行路由跳转,都需要小心翼翼的写 path

如果稍微写错一点点,那么将无法跳转页面

以 React 为例

而且 path 是纯字符串,没有 Typescript 类型提示

你写错了他也不会告诉你

如果你想有提示,只能自己手动挨个写类型,这很麻烦

那有没有一种办法,让 Typescript 自动推断我的 path 呢

当然有!!

解决方案一

as const

添加这个后就变成常量了,然后获取他的类型即可

在 Typescript 里,typeof 是获取他的类型

然后用中括号([]),获取某个成员,可以是 字符串number

这里写 number 就是获取每个数组的成员

最后再取 path 字段,即可推导出路径类型


但是,好用吗?

还行吧,至少能用


麻烦吗?

有点麻烦,要挨个添加上 as const

如果对大型项目修改,还是有一定的工作量的


有更好地解决方案吗?

当然有,现在就来告诉你


解决方案二

先写个路由类型吧

ts 复制代码
import type { RouteObject } from 'react-router-dom'

export type RouteItem<T extends string> =
  Omit<RouteObject, 'path'>
  & {
    path: T
  }

应该有些小伙伴会困惑,我是怎么知道 RouteObject 是 React 的路由类型呢?

我是怎么知道从哪导入的呢?

其实用 VSCode 就能知道

然后写上类型名字,按下 Ctrl + .

开启智能导入即可,详见我的文章教学

# 【最高效编码指南】也许你不会用VSCode

# VSCode 工具技巧集合

回到类型上来,我这个类型把原本的 path 排除掉,然后拼接上一个泛型

因为 React 定义的 path 类型是纯字符串 string

这种无法开启任何类型推断,必须用泛型才行

ts 复制代码
import type { RouteObject } from 'react-router-dom'

export type RouteItem<T extends string> =
  Omit<RouteObject, 'path'>
  & {
    path: T
  }

const 泛型

ts 复制代码
function genRoutes<const T extends string>(routes: RouteItem<T>[]) {
  return routes
}

注意到了吗,我给函数的泛型加了 const

大多数人应该没用过吧?

那么他有什么效果呢?

接着往下看吧

利用这个函数,即可推断出类型,只需要把数组给他即可

看到了吗?我的 path 并没有标注 as const

但是返回的数组给我自动推断了

这样对于大型项目的改动侵入性,可以说为零

仅仅是添加一个函数即可实现


接下来取出路径类型即可,再重写一下路由方法即可

或者重写路由类型也行

ts 复制代码
export type routePath = typeof myRoutes[number]['path']

重写路由方法

在 React 中,导出的路由对象上,有个 navigate 方法

如果不使用 Hook useNavigate 的话,用它也能实现路由导航

ts 复制代码
export const router = createBrowserRouter(...)

接下来重新标注一下类型即可

Parameters 是拿到函数的参数,是个元组,取索引 [1],拿到配置类型

ts 复制代码
/**
 * 带有类型推断的路由跳转
 */
export const routerTo = (
  path: routePath,
  opts?: Parameters<typeof router['navigate']>[1]
) => {
  router.navigate(path, opts)
}

更为彻底的,重写路由接口类型

写法就是排除掉原本的 navigate 函数类型

自己再重写一遍,可惜的是,React 没有导出 createBrowserRouter 的返回类型

所以无法实现了

ts 复制代码
type NavigateParameters = Parameters<Router['navigate']>
type NavigateReturn = ReturnType<Router['navigate']>

type MyRouter = Omit<Router, 'navigate'> & {
  navigate: (path: routePath, opts?: NavigateParameters[1]) => NavigateReturn
}

如果用 typeof 获取类型,又会循环引用自身

所以到此为止吧,功能已经实现了

相关推荐
lh_12544 分钟前
ECharts 地图开发入门
前端·javascript·echarts
jjw_zyfx6 分钟前
成熟的前端vue vite websocket,Django后端实现方案包含主动断开websocket连接的实现
前端·vue.js·websocket
Mikey_n42 分钟前
前台调用接口的方式及速率对比
前端
周之鸥1 小时前
使用 Electron 打包可执行文件和资源:完整实战教程
前端·javascript·electron
我爱吃朱肉1 小时前
HTMLCSS模板实现水滴动画效果
前端·css·css3
机器视觉知识推荐、就业指导1 小时前
开源QML控件:进度条滑动控件(含源码下载链接)
前端·qt·开源·qml
前端snow1 小时前
前端全栈第二课:用typeorm向数据库添加数据---一对多关系
前端·javascript
難釋懷1 小时前
Shell脚本-for循环语法结构
前端·chrome
全栈老李技术面试1 小时前
【高频考点精讲】async/await原理剖析:Generator和Promise的完美结合
前端·javascript·css·vue·html·react·面试题
kadog1 小时前
PubMed PDF下载 cloudpmc-viewer-pow逆向
前端·javascript·人工智能·爬虫·pdf