From: pikax Date: Thu, 8 Apr 2021 19:30:00 +0000 (+0100) Subject: supporting child named routes X-Git-Tag: v4.1.0~122 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0019cba5ba27ce1de9b529e41193797b37dbd8cf;p=thirdparty%2Fvuejs%2Frouter.git supporting child named routes --- diff --git a/src/router.ts b/src/router.ts index 6e902a40..4f4f704e 100644 --- a/src/router.ts +++ b/src/router.ts @@ -254,16 +254,14 @@ export interface Router { * * @param to - Route location to navigate to */ - // push(to: RouteLocationRaw): Promise + 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 + // push(to: RouteNamedLocation): Promise /** * Programmatically navigate to a new URL by replacing the current entry in diff --git a/src/types/index.ts b/src/types/index.ts index e7e507d0..438b524f 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -4,6 +4,7 @@ import { Ref, ComponentPublicInstance, Component, DefineComponent } from 'vue' import { RouteRecord, RouteRecordNormalized } from '../matcher/types' import { HistoryState } from '../history/common' import { NavigationFailure } from '../errors' +import { NamedLocationMap } from './named' export { RouteNamedLocation, @@ -72,7 +73,7 @@ export interface LocationAsName { * @internal */ export interface LocationAsRelativeRaw { - name?: RouteRecordName + name?: {} extends NamedLocationMap ? RouteRecordName : keyof NamedLocationMap params?: RouteParamsRaw } diff --git a/src/types/named.ts b/src/types/named.ts index 663c3b5b..750febe2 100644 --- a/src/types/named.ts +++ b/src/types/named.ts @@ -1,15 +1,99 @@ -import { RouteLocationOptions, RouteRecordRaw } from '.' +import { RouteLocationOptions, RouteRecordRaw, _RouteRecordBase } from '.' + +// export type ExtractNameRoute> = +// | ([T] extends [{ name: string }] ? { [K in T['name']]: unknown } : never) +// | ([T] extends [{ children: Readonly }] +// ? ExtractNamedRoutes +// : never) + +export type ExtractNamedRoute> = [ + T +] extends [{ name: string; readonly children?: any[] }] + ? { [K in T['name']]: unknown } & + ([T['children']] extends [Readonly>] + ? ExtractNamedRoutes + : {}) + : never 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 + T extends Readonly> | undefined +> = T extends Readonly> + ? // ? [R] extends [{ name: string /*params?: infer Params*/ }] + [R] extends [_RouteRecordBase] + ? ExtractNamedRoute + : {} : never +// const routes = [ +// { +// path: 'my-path', +// name: 'test', +// component: Comp, +// }, +// { +// path: 'my-path', +// name: 'my-other-path', +// component: Comp, +// }, +// { +// path: 'random', +// name: 'tt', +// children: [ +// { +// path: 'random-child', +// name: 'random-child', +// component: Comp, +// }, +// ], +// }, +// ] as const + +// type TypedRoutes = ExtractNamedRoutes + +// declare const Comp: () => any + +// const routes = [ +// { +// path: 'my-path', +// name: 'test', +// component: Comp, +// }, +// { +// path: 'my-path', +// // name: 'my-other-path', +// component: Comp, +// }, +// ] as const + +// type XXX = ExtractNamedRoutes< +// Readonly< +// [ +// { +// path: 'ttt' +// name: 'sddsd' +// component: any +// children: [ +// { +// path: 'ttt' +// name: 'child' +// component: any +// }, +// { +// path: 'ttt' +// name: 'child-other' +// component: any +// } +// ] +// } +// ] +// > +// > + +// interface XXW extends XXX {} + +// const xxx2: XXW +// type TypedRoutes = ExtractNamedRoutes + // export type ExtractNamedRoutes< // T extends Array | Readonly> // > = T extends Array @@ -40,25 +124,25 @@ export interface RouteNamedLocation< // params: NamedLocationMap[T] } -declare const r: [ - { - name: 'test' - params: { - number: 1 - } - }, - { - name: 'LOL' - params: { - sss: 'sss' - } - }, - { - name: 'other' - }, - { - path: 'ssss' - } -] +// declare const r: [ +// { +// name: 'test' +// params: { +// number: 1 +// } +// }, +// { +// name: 'LOL' +// params: { +// sss: 'sss' +// } +// }, +// { +// name: 'other' +// }, +// { +// path: 'ssss' +// } +// ] -declare const x: ExtractNamedRoutes +// declare const x: ExtractNamedRoutes diff --git a/test-dts/namedRoutes.test-d.ts b/test-dts/namedRoutes.test-d.ts index 93cc9541..8ecc91ba 100644 --- a/test-dts/namedRoutes.test-d.ts +++ b/test-dts/namedRoutes.test-d.ts @@ -1,5 +1,3 @@ -// NOTE `ExtractNamedRoutes` is not exposed on build, you might need to add export to the type manually - import { ExtractNamedRoutes, Router } from './index' import { DefineComponent } from 'vue' @@ -10,18 +8,24 @@ const routes = [ 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, -] + }, + { + path: 'random', + name: 'tt', + children: [ + { + path: 'random-child', + name: 'random-child', + component: Comp, + }, + ], + }, +] as const type TypedRoutes = ExtractNamedRoutes @@ -32,5 +36,10 @@ declare module './index' { declare const router: Router router.push({ - name: '', + name: 'my-other-path', +}) + +router.push({ + // @ts-expect-error location name does not exist + name: 'random-location', })