TypeScript 支持

vitarx-router 提供了完善的 TypeScript 支持,通过接口扩展可以实现路由元数据的类型提示和路由导航的参数类型检查。

RouteMetaData 扩展

通过扩展 RouteMetaData 接口,可以为路由的 meta 字段添加类型提示:

ts
// 在项目的全局类型声明文件中(如 env.d.ts)
declare module 'vitarx-router' {
  interface RouteMetaData {
    /** 页面标题 */
    title?: string
    /** 页面图标 */
    icon?: string
    /** 是否需要登录认证 */
    requiresAuth?: boolean
  }
}

// 必须导出空对象,使此文件成为模块
export {}

扩展后,在使用 meta 时会获得类型提示:

ts
const router = createRouter({
  routes: [
    {
      path: '/admin',
      component: Admin,
      meta: {
        title: '管理后台', // ✅ 有类型提示
        icon: 'settings', // ✅ 有类型提示
        requiresAuth: true, // ✅ 有类型提示
        unknown: true // ❌ 类型错误
      }
    }
  ]
})

在组件中访问 meta 时同样有类型提示:

tsx
import { useRoute } from 'vitarx-router'

function AdminPage() {
  const route = useRoute()
  // route.meta.title — string | undefined
  // route.meta.requiresAuth — boolean | undefined
  if (route.meta.requiresAuth) {
    // 需要认证的逻辑
  }
  return <h1>{route.meta.title}</h1>
}

RouteIndexMap 扩展

通过扩展 RouteIndexMap 接口,可以为路由导航提供参数类型检查:

ts
declare module 'vitarx-router' {
  interface RouteIndexMap {
    /** 用户详情路由 */
    user: {
      params: { id: string }
    }
    /** 文章详情路由 */
    post: {
      params: { slug: string }
    }
    /** 首页 — 无参数 */
    home: {}
  }
}

export {}

扩展后,使用 router.push / router.replace 时会自动校验参数:

ts
// ✅ 正确:提供了必需的 id 参数
router.push({ index: 'user', params: { id: '123' } })

// ❌ 类型错误:缺少 id 参数
router.push({ index: 'user' })

// ❌ 类型错误:参数名错误
router.push({ index: 'user', params: { userId: '123' } })

// ✅ 正确:无参数路由
router.push('home')

INFO

RouteIndexMap 的键是路由的 name,值中的 params 定义了该路由需要的参数类型。扩展后,router.pushrouter.replace 等方法会根据此接口进行类型推断。

路由类型声明

使用文件路由时,可以通过 dts 选项自动生成类型声明文件:

ts
// vite.config.ts
VitarxRouter({
  dts: true // 生成 router.d.ts
})

生成的类型声明文件大致如下:

ts
// router.d.ts(自动生成,请勿手动修改)
declare module 'vitarx-router' {
  interface RouteIndexMap {
    about: {}
    user: { params: { id: string } }
    admin: {}
    // ...其他路由
  }
}

export {}

WARNING

自动生成的类型声明文件会覆盖手动修改的内容。如果你需要添加自定义类型,请在单独的类型声明文件中扩展,而不是修改自动生成的文件。

完整示例

ts
// src/types/router.d.ts
import 'vitarx-router'

declare module 'vitarx-router' {
  // 扩展路由元数据类型
  interface RouteMetaData {
    /** 页面标题 */
    title?: string
    /** 页面图标(图标类名) */
    icon?: string
    /** 是否需要登录认证 */
    requiresAuth?: boolean
    /** 菜单排序权重 */
    order?: number
  }

  // 扩展路由索引映射
  interface RouteIndexMap {
    home: {}
    about: {}
    user: { params: { id: string } }
    post: { params: { slug: string } }
    admin: {}
    'admin-users': {}
    'admin-posts': {}
  }
}

export {}
ts
// src/router/index.ts
import { createRouter } from 'vitarx-router'
import { lazy } from 'vitarx'

const router = createRouter({
  routes: [
    {
      path: '/',
      name: 'home',
      component: lazy(() => import('../pages/Home.tsx')),
      meta: { title: '首页', icon: 'home' }
    },
    {
      path: '/user/{id}',
      name: 'user',
      component: lazy(() => import('../pages/User.tsx')),
      meta: { title: '用户详情', requiresAuth: true }
    }
  ]
})

// ✅ 类型安全的导航
router.push({ index: 'user', params: { id: '123' } })