Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

types: add RouteMeta interface to enable module augmentation #3385

Merged
merged 3 commits into from Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions types/index.d.ts
Expand Up @@ -5,6 +5,7 @@ export default VueRouter

export {
RouterMode,
RouteMeta,
RawLocation,
RedirectOption,
RouterOptions,
Expand Down
8 changes: 5 additions & 3 deletions types/router.d.ts
Expand Up @@ -126,7 +126,7 @@ interface _RouteConfigBase {
children?: RouteConfig[]
redirect?: RedirectOption
alias?: string | string[]
meta?: any
meta?: RouteMeta
beforeEnter?: NavigationGuard
caseSensitive?: boolean
pathToRegexpOptions?: PathToRegexpOptions
Expand All @@ -153,7 +153,7 @@ export interface RouteRecord {
parent?: RouteRecord
redirect?: RedirectOption
matchAs?: string
meta: any
meta: RouteMeta
beforeEnter?: (
route: Route,
redirect: (location: RawLocation) => void,
Expand Down Expand Up @@ -205,5 +205,7 @@ export interface Route {
fullPath: string
matched: RouteRecord[]
redirectedFrom?: string
meta?: any
meta?: RouteMeta
}

export interface RouteMeta extends Record<string | number | symbol, any> {}
8 changes: 5 additions & 3 deletions types/test/index.ts
Expand Up @@ -18,7 +18,9 @@ const Abc = { template: '<div>abc</div>' }
const Async = () => Promise.resolve({ template: '<div>async</div>' })

let err: any
if (VueRouter.isNavigationFailure(err, VueRouter.NavigationFailureType.aborted)) {
if (
VueRouter.isNavigationFailure(err, VueRouter.NavigationFailureType.aborted)
) {
err.from.fullPath.split('/')
}

Expand Down Expand Up @@ -104,7 +106,7 @@ const router = new VueRouter({
abc: Abc,
asyncComponent: Async
},
meta: { auth: true },
meta: { auth: true, nested: { foo: '' } },
beforeEnter(to, from, next) {
to.params
from.params
Expand Down Expand Up @@ -229,7 +231,7 @@ const Components: (
| AsyncComponent
)[] = router.getMatchedComponents()

const match: Route = router.match('/more');
const match: Route = router.match('/more')

const vm = new Vue({
router,
Expand Down
45 changes: 45 additions & 0 deletions types/test/meta.ts
@@ -0,0 +1,45 @@
import VueRouter from '../index'

const component = { template: '<div>home</div>' }

declare module '../index' {
export interface RouteMeta {
requiresAuth?: boolean
nested: { foo: string }
}
}

const router = new VueRouter({
routes: [
{
path: '/',
component,
meta: {
requiresAuth: true,
// still allowed
other: true,
nested: {
foo: 'bar'
}
}
},
{
path: '/foo',
component,
// @ts-expect-error
meta: {}
}
]
})

router.beforeEach(to => {
// should pass
if (to.meta!.requiresAuth === true) {
}
// still pass because any
if (to.meta!.lol === true) {
}
// @ts-expect-error: nested will never be true
if (to.meta!.nested === true) {
}
})