Skip to content

Commit 260f737

Browse files
types: add RouteMeta interface to enable module augmentation (#3385)
Co-authored-by: Eduardo San Martin Morote <[email protected]>
1 parent 306602d commit 260f737

File tree

4 files changed

+56
-6
lines changed

4 files changed

+56
-6
lines changed

Diff for: types/index.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export default VueRouter
55

66
export {
77
RouterMode,
8+
RouteMeta,
89
RawLocation,
910
RedirectOption,
1011
RouterOptions,

Diff for: types/router.d.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ interface _RouteConfigBase {
126126
children?: RouteConfig[]
127127
redirect?: RedirectOption
128128
alias?: string | string[]
129-
meta?: any
129+
meta?: RouteMeta
130130
beforeEnter?: NavigationGuard
131131
caseSensitive?: boolean
132132
pathToRegexpOptions?: PathToRegexpOptions
@@ -153,7 +153,7 @@ export interface RouteRecord {
153153
parent?: RouteRecord
154154
redirect?: RedirectOption
155155
matchAs?: string
156-
meta: any
156+
meta: RouteMeta
157157
beforeEnter?: (
158158
route: Route,
159159
redirect: (location: RawLocation) => void,
@@ -205,5 +205,7 @@ export interface Route {
205205
fullPath: string
206206
matched: RouteRecord[]
207207
redirectedFrom?: string
208-
meta?: any
208+
meta?: RouteMeta
209209
}
210+
211+
export interface RouteMeta extends Record<string | number | symbol, any> {}

Diff for: types/test/index.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ const Abc = { template: '<div>abc</div>' }
1818
const Async = () => Promise.resolve({ template: '<div>async</div>' })
1919

2020
let err: any
21-
if (VueRouter.isNavigationFailure(err, VueRouter.NavigationFailureType.aborted)) {
21+
if (
22+
VueRouter.isNavigationFailure(err, VueRouter.NavigationFailureType.aborted)
23+
) {
2224
err.from.fullPath.split('/')
2325
}
2426

@@ -104,7 +106,7 @@ const router = new VueRouter({
104106
abc: Abc,
105107
asyncComponent: Async
106108
},
107-
meta: { auth: true },
109+
meta: { auth: true, nested: { foo: '' } },
108110
beforeEnter(to, from, next) {
109111
to.params
110112
from.params
@@ -229,7 +231,7 @@ const Components: (
229231
| AsyncComponent
230232
)[] = router.getMatchedComponents()
231233

232-
const match: Route = router.match('/more');
234+
const match: Route = router.match('/more')
233235

234236
const vm = new Vue({
235237
router,

Diff for: types/test/meta.ts

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import VueRouter from '../index'
2+
3+
const component = { template: '<div>home</div>' }
4+
5+
declare module '../index' {
6+
export interface RouteMeta {
7+
requiresAuth?: boolean
8+
nested: { foo: string }
9+
}
10+
}
11+
12+
const router = new VueRouter({
13+
routes: [
14+
{
15+
path: '/',
16+
component,
17+
meta: {
18+
requiresAuth: true,
19+
// still allowed
20+
other: true,
21+
nested: {
22+
foo: 'bar'
23+
}
24+
}
25+
},
26+
{
27+
path: '/foo',
28+
component,
29+
// @ts-expect-error
30+
meta: {}
31+
}
32+
]
33+
})
34+
35+
router.beforeEach(to => {
36+
// should pass
37+
if (to.meta!.requiresAuth === true) {
38+
}
39+
// still pass because any
40+
if (to.meta!.lol === true) {
41+
}
42+
// @ts-expect-error: nested will never be true
43+
if (to.meta!.nested === true) {
44+
}
45+
})

0 commit comments

Comments
 (0)