【奇淫技巧】让你的路由跳转拥有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 获取类型,又会循环引用自身

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

相关推荐
DanB247 分钟前
html复习
javascript·microsoft·html
汉得数字平台12 分钟前
【鲲苍提效】全面洞察用户体验,助力打造高性能前端应用
前端·前端监控
花海如潮淹18 分钟前
前端性能追踪工具:用户体验的毫秒战争
前端·笔记·ux
_丿丨丨_5 小时前
XSS(跨站脚本攻击)
前端·网络·xss
天天进步20155 小时前
前端安全指南:防御XSS与CSRF攻击
前端·安全·xss
呼啦啦呼啦啦啦啦啦啦6 小时前
利用pdfjs实现的pdf预览简单demo(包含翻页功能)
android·javascript·pdf
拾光拾趣录8 小时前
括号生成算法
前端·算法
拾光拾趣录8 小时前
requestIdleCallback:让你的网页如丝般顺滑
前端·性能优化
前端 贾公子9 小时前
vue-cli 模式下安装 uni-ui
前端·javascript·windows
拾光拾趣录9 小时前
链表合并:双指针与递归
前端·javascript·算法