Description
What problem does this feature solve?
Currently a route's meta field is listed as "any". This makes it impossible for users to define the structure of their own metadata. As an example, I wish to use the "meta" property for middleware. I've created a Middleware type and would like an interface like the following:
declare module "vue-router" {
interface Route {
meta: {
middleware?: Middleware[]
}
}
}
If I try to define it this way, I get an error saying that all declarations of "meta" must have identical modifiers, and that "meta" was already defined in router.d.ts... However if I DON'T define it this way then I lose the ability to statically type check this property and catch developers who accidentally pass an incorrect type (e.g. passing a string containing the middleware's name, instead of the middleware object itself)
Now there's admittedly a limitation of this. Currently, it's possible to pass a non-object for the meta of a route. If you want to stick just a number or a string in there, it's completely valid. Making this a user-extensible interface would eliminate that use case (and therefore be a breaking API change) -- but I find it highly suspect that anyone is using the meta field in that way in a production app of any meaningful size. Without key-value pairs, storing only a single string into the "meta" field doesn't feel very useful.
What does the proposed API look like?
export interface Route {
path: string
name?: string | null
hash: string
query: Dictionary<string | (string | null)[]>
params: Dictionary<string>
fullPath: string
matched: RouteRecord[]
redirectedFrom?: string
meta?: {} // <-- replaced "any" with "{}"
}