TypeScript 安全路由名称?

问题描述 投票:0回答:4

考虑以下代码:

const router = useRouter()

await router.push({
  name: 'NonExistingRoute', // no typescript error ):
}) 

给出了一个不存在的路由名称,但没有发生 TypeScript 错误。相反,该问题只会在运行时被注意到。有什么方法可以得到编译时错误吗?

vue-router vuejs3
4个回答
1
投票

也许你可以把它包装在一个只接受类型路由字符串的实用函数中

const router = useRouter()
export type NamedRoute = "login" | "logout" | "user-profile";

export async function goToNamedRoute(name: NamedRoute): Promise<void> {
    return router.push({name});
}

0
投票

简而言之

对于存在的编译错误,代码需要有明显的错误,引用不存在的文件,语法错误等

听起来您确实想在这里解决其他一些问题……即为什么你的应用程序中有不存在的路线名称?

无论如何,也许您可以通过编程方式避免错误,例如

 let r = router.resolve({name: 'NonExistingRoute'});
 if (r.resolved.matched.length > 0){
    // exists
 } else {
    // doesn't exist
 }

0
投票

如果你想依赖 Typescript 来检测错误的路由,你可能只使用枚举或封闭类型?,尽管这肯定需要一些组合。可能的一种方法是:

enum Cities {
   NY, 
   London
}

function routeCreator(city: Cities, restOfPath?: string){
    //combine paths somehow, e.g.
    if(!restOfPath) return `/${Cities[city]}/`;
    return `/${Cities[city]}/${restOfPath}`
}


0
投票

我对这个困境的解决方案

在 routes.ts 中定义你的路线

import { RouteLocationRaw } from 'vue-router'

type RouteFunction = (...args: any[]) => RouteLocationRaw

export const routes = {
  login: () => ({ name: 'Login' }) as const,
  viewProfile: (userId: string) => ({ name: 'ViewProfile', params: { userId } }) as const,
  ...
} satisfies Readonly<Record<string, RouteFunction>>

export type Routes = typeof routes
export type NamedRoute = ReturnType<Routes[keyof Routes]>['name']

请注意,每条路线都需要是

as const
,否则打字稿会将['name']属性扩大到任何
string
.

然后实际的路由器被定义为

import { RouteRecordRaw, createRouter, createWebHistory } from 'vue-router'
import { NamedRoute } from '@/router/routes'

type NamedRouteRecordParent = { name?: NamedRoute, children: NamedRouteRecord[] }
type NamedRouteRecordChild = { name: NamedRoute }
type NamedRouteRecord = Omit<RouteRecordRaw, 'name' | 'children'> & NamedRouteRecordParent | NamedRouteRecordChild

const routes: NamedRouteRecord[] = [
  { name: 'Login', path: '/login' },
  { name: 'ViewProfile', path: '/view-profile/:userId' },
]

export const router = createRouter({
  history: createWebHistory(),
  routes: routes as RouteRecordRaw[],
})

强制开发人员仅命名与

routes.ts
中找到的记录相匹配的路由。如所写,“父”记录不必命名。

© www.soinside.com 2019 - 2024. All rights reserved.