From: pikax Date: Thu, 8 Apr 2021 17:16:20 +0000 (+0100) Subject: feat: support for typescript named routes X-Git-Tag: v4.1.0~124 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29aebb6905d3b67c29955297139eced51cfa155d;p=thirdparty%2Fvuejs%2Frouter.git feat: support for typescript named routes --- diff --git a/src/index.ts b/src/index.ts index 7c583a21..d5975392 100644 --- a/src/index.ts +++ b/src/index.ts @@ -47,6 +47,10 @@ export type { RouteLocationMatched, RouteLocationOptions, RouteRecordRedirectOption, + RouteNamedLocation, + defineRoutes, + NamedLocationMap, + ExtractNamedRoutes, // route records _RouteRecordBase, RouteMeta, diff --git a/src/router.ts b/src/router.ts index fe511b8d..f731505a 100644 --- a/src/router.ts +++ b/src/router.ts @@ -13,6 +13,8 @@ import { RouteLocationOptions, MatcherLocationRaw, RouteParams, + RouteNamedLocation, + NamedLocationMap, } from './types' import { RouterHistory, HistoryState, NavigationType } from './history/common' import { @@ -253,6 +255,16 @@ export interface Router { * @param to - Route location to navigate to */ push(to: RouteLocationRaw): Promise + /** + * Programmatically navigate to a new URL by pushing an entry in the history + * stack. + * + * @param to - typed route location + */ + push( + to: RouteNamedLocation + ): Promise + /** * Programmatically navigate to a new URL by replacing the current entry in * the history stack. diff --git a/src/types/index.ts b/src/types/index.ts index d4709cc1..e7e507d0 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -5,6 +5,13 @@ import { RouteRecord, RouteRecordNormalized } from '../matcher/types' import { HistoryState } from '../history/common' import { NavigationFailure } from '../errors' +export { + RouteNamedLocation, + NamedLocationMap, + defineRoutes, + ExtractNamedRoutes, +} from './named' + export type Lazy = () => Promise export type Override = Pick> & U diff --git a/src/types/named.ts b/src/types/named.ts new file mode 100644 index 00000000..c01521af --- /dev/null +++ b/src/types/named.ts @@ -0,0 +1,63 @@ +import { RouteLocationOptions, RouteRecordRaw } from '.' + +export type ExtractNamedRoutes< + T extends Array +> = T extends Array + ? [R] extends [{ name: string /*params?: infer Params*/ }] + ? { + [K in R['name']]: unknown /*TODO add params*/ /*R['params'] extends Params ? Params : Params*/ + } + : never + : never + +// export type ExtractNamedRoutes< +// T extends Array | Readonly> +// > = T extends Array +// ? [R] extends [{ name: string /*params?: infer Params*/ }] +// ? { +// [K in R['name']]: unknown /*TODO add params*/ /*R['params'] extends Params ? Params : Params*/ +// } +// : never +// : T extends Readonly> +// ? [R] extends [{ name: string /*params?: infer Params*/ }] +// ? { +// [K in R['name']]: unknown /*TODO add params*/ /*R['params'] extends Params ? Params : Params*/ +// } +// : never +// : never + +export function defineRoutes< + T extends Array> +>(routes: T): ExtractNamedRoutes { + return routes as any +} +export interface NamedLocationMap {} + +export interface RouteNamedLocation + extends RouteLocationOptions { + name: T + params: NamedLocationMap[T] +} + +declare const r: [ + { + name: 'test' + params: { + number: 1 + } + }, + { + name: 'LOL' + params: { + sss: 'sss' + } + }, + { + name: 'other' + }, + { + path: 'ssss' + } +] + +declare const x: ExtractNamedRoutes diff --git a/test-dts/namedRoutes.test-d.ts b/test-dts/namedRoutes.test-d.ts new file mode 100644 index 00000000..92870cdf --- /dev/null +++ b/test-dts/namedRoutes.test-d.ts @@ -0,0 +1,29 @@ +import { defineRoutes } from './index' +import { DefineComponent } from 'vue' + +declare const Comp: DefineComponent + +const routes = defineRoutes([ + { + path: 'my-path', + name: 'test', + component: Comp, + } as const, + { + path: 'my-path', + name: 'my-other-path', + component: Comp, + } as const, + + // { + // path: 'my-path', + // component: Comp, + // } as const, +]) + +declare module './index' { + interface RouteMeta { + requiresAuth?: boolean + nested: { foo: string } + } +}