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

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

相关推荐
前端拾光者2 分钟前
利用D3.js实现数据可视化的简单示例
开发语言·javascript·信息可视化
Json_1817901448020 分钟前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
风尚云网43 分钟前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
木子02041 小时前
前端VUE项目启动方式
前端·javascript·vue.js
GISer_Jing1 小时前
React核心功能详解(一)
前端·react.js·前端框架
捂月1 小时前
Spring Boot 深度解析:快速构建高效、现代化的 Web 应用程序
前端·spring boot·后端
深度混淆1 小时前
实用功能,觊觎(Edge)浏览器的内置截(长)图功能
前端·edge
Smartdaili China1 小时前
如何在 Microsoft Edge 中设置代理: 快速而简单的方法
前端·爬虫·安全·microsoft·edge·社交·动态住宅代理
秦老师Q1 小时前
「Chromeg谷歌浏览器/Edge浏览器」篡改猴Tempermongkey插件的安装与使用
前端·chrome·edge
滴水可藏海1 小时前
Chrome离线安装包下载
前端·chrome