-
-
Notifications
You must be signed in to change notification settings - Fork 491
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
feat: experimental typed routes #3142
Changes from 8 commits
a37559c
65becf5
2bb26c9
1214bd2
63e553f
d05df07
d836d51
88fe1e3
2f7b3d2
10353ac
87101f7
d937c52
50030ea
113a490
5226fc0
16ac01a
e3ec9fa
40a6543
d661a2d
91539df
4a407ac
cc6de7c
385db97
56c6f51
312efe2
352ce15
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import { defineBuildConfig } from 'unbuild' | ||
|
||
export default defineBuildConfig({ | ||
externals: ['node:fs', 'node:url', 'webpack', '@babel/parser'] | ||
externals: ['node:fs', 'node:url', 'webpack', '@babel/parser', 'unplugin-vue-router', 'unplugin-vue-router/options'] | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,78 @@ declare module '#app' { | |
} | ||
} | ||
|
||
// This needs to be generated, or else `RouteMapI18n` will fall back to `RouteMapGeneric` | ||
// declare module 'vue-router' { | ||
// import type { RouteNamedMapI18n } from 'vue-router/auto-routes' | ||
|
||
// export interface TypesConfig { | ||
// RouteNamedMapI18n: RouteNamedMapI18n | ||
// } | ||
// } | ||
|
||
declare module 'vue-router' { | ||
export type RouteMapI18n = | ||
TypesConfig extends Record<'RouteNamedMapI18n', infer RouteNamedMap> ? RouteNamedMap : RouteMapGeneric | ||
|
||
export type RouteLocationRawI18n<Name extends keyof RouteMapI18n = keyof RouteMapI18n> = | ||
RouteMapGeneric extends RouteMapI18n | ||
? RouteLocationAsStringI18n | RouteLocationAsRelativeGeneric | RouteLocationAsPathGeneric | ||
: | ||
| _LiteralUnion<RouteLocationAsStringTypedList<RouteMapI18n>[Name], string> | ||
| RouteLocationAsRelativeTypedList<RouteMapI18n>[Name] | ||
|
||
export type RouteLocationResolvedI18n<Name extends keyof RouteMapI18n = keyof RouteMapI18n> = | ||
RouteMapGeneric extends RouteMapI18n | ||
? RouteLocationResolvedGeneric | ||
: RouteLocationResolvedTypedList<RouteMapI18n>[Name] | ||
|
||
export interface RouteLocationNormalizedLoadedTypedI18n< | ||
RouteMapI18n extends RouteMapGeneric = RouteMapGeneric, | ||
Name extends keyof RouteMapI18n = keyof RouteMapI18n | ||
> extends RouteLocationNormalizedLoadedGeneric { | ||
name: Extract<Name, string | symbol> | ||
params: RouteMapI18n[Name]['params'] | ||
} | ||
export type RouteLocationNormalizedLoadedTypedListI18n<RouteMapOriginal extends RouteMapGeneric = RouteMapGeneric> = { | ||
[N in keyof RouteMapOriginal]: RouteLocationNormalizedLoadedTypedI18n<RouteMapOriginal, N> | ||
} | ||
export type RouteLocationNormalizedLoadedI18n<Name extends keyof RouteMapI18n = keyof RouteMapI18n> = | ||
RouteMapGeneric extends RouteMapI18n | ||
? RouteLocationNormalizedLoadedGeneric | ||
: RouteLocationNormalizedLoadedTypedListI18n<RouteMapI18n>[Name] | ||
|
||
type _LiteralUnion<LiteralType, BaseType extends string = string> = LiteralType | (BaseType & Record<never, never>) | ||
|
||
export type RouteLocationAsStringI18n<Name extends keyof RouteMapI18n = keyof RouteMapI18n> = | ||
RouteMapGeneric extends RouteMapI18n | ||
? string | ||
: _LiteralUnion<RouteLocationAsStringTypedList<RouteMapI18n>[Name], string> | ||
|
||
export type RouteLocationAsStringI18n<Name extends keyof RouteMapI18n = keyof RouteMapI18n> = | ||
RouteMapGeneric extends RouteMapI18n | ||
? string | ||
: _LiteralUnion<RouteLocationAsStringTypedList<RouteMapI18n>[Name], string> | ||
|
||
export type RouteLocationAsRelativeI18n<Name extends keyof RouteMapI18n = keyof RouteMapI18n> = | ||
RouteMapGeneric extends RouteMapI18n | ||
? RouteLocationAsRelativeGeneric | ||
: RouteLocationAsRelativeTypedList<RouteMapI18n>[Name] | ||
|
||
export type RouteLocationAsPathI18n<Name extends keyof RouteMapI18n = keyof RouteMapI18n> = | ||
RouteMapGeneric extends RouteMapI18n ? RouteLocationAsPathGeneric : RouteLocationAsPathTypedList<RouteMapI18n>[Name] | ||
|
||
/** | ||
* Helper to generate a type safe version of the {@link RouteLocationAsRelative} type. | ||
*/ | ||
export interface RouteLocationAsRelativeTyped< | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this the same type exported by the router? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm most of the types should be the same except suffixed with Reasoning behind redefining the same types but suffixed is to use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesnβt extending the same route map from Vue router works? Or do you need to have two separate route maps? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we're generating routes for each locale (depending on the routing strategy) and custom localized route the generated types are localized, this PR generates Some examples to illustrate the problem we're trying to solve: Path completion (not desirable when using custom routes) I guess this is specific to i18n, I doubt there are other use cases where generating a separate map is necessary π€ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would need to try it out to see the needed final types. I was hoping the types were flexible enough to at least keep things typer for the router methods. I18n methods could use extra types for localized route names (that seems to be the main difference) |
||
RouteMapI18n extends RouteMapGeneric = RouteMapGeneric, | ||
Name extends keyof RouteMapI18n = keyof RouteMapI18n | ||
> extends RouteLocationAsRelativeGeneric { | ||
name?: Extract<Name, string | symbol> | ||
params?: RouteMapI18n[Name]['paramsRaw'] | ||
} | ||
} | ||
|
||
declare global { | ||
var $t: Composer['t'] | ||
var $rt: Composer['rt'] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wow! This typing is too amazing!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should reference the original source types π I had to redefine/reimplement a bunch of internal types of
vue-router
and uvr, so the credits for these go to @posva