]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
supporting child named routes
authorpikax <carlos@hypermob.co.uk>
Thu, 8 Apr 2021 19:30:00 +0000 (20:30 +0100)
committerEduardo San Martin Morote <posva@users.noreply.github.com>
Thu, 30 Jun 2022 07:59:00 +0000 (09:59 +0200)
src/router.ts
src/types/index.ts
src/types/named.ts
test-dts/namedRoutes.test-d.ts

index 6e902a409b8a3c95c09097579ce5d33f13a47124..4f4f704ed8a8be9d8d672cb7974cffb95a84bf54 100644 (file)
@@ -254,16 +254,14 @@ export interface Router {
    *
    * @param to - Route location to navigate to
    */
-  // push(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>
+  push(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>
   /**
    * Programmatically navigate to a new URL by pushing an entry in the history
    * stack.
    *
    * @param to - typed route location
    */
-  push(
-    to: RouteNamedLocation
-  ): Promise<NavigationFailure | void | undefined>
+  // push(to: RouteNamedLocation): Promise<NavigationFailure | void | undefined>
 
   /**
    * Programmatically navigate to a new URL by replacing the current entry in
index e7e507d0b0f3e038601d7be5619469f11e495334..438b524f61bbad01e6e0cfd02451495c033ac69d 100644 (file)
@@ -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
 }
 
index 663c3b5bc077495617763aa44386d30dc21ecfc3..750febe23c5da7472678c2d771efed6ff03b7527 100644 (file)
@@ -1,15 +1,99 @@
-import { RouteLocationOptions, RouteRecordRaw } from '.'
+import { RouteLocationOptions, RouteRecordRaw, _RouteRecordBase } from '.'
+
+// export type ExtractNameRoute<T extends Readonly<RouteRecordRaw>> =
+//   | ([T] extends [{ name: string }] ? { [K in T['name']]: unknown } : never)
+//   | ([T] extends [{ children: Readonly<RouteRecordRaw[]> }]
+//       ? ExtractNamedRoutes<T['children']>
+//       : never)
+
+export type ExtractNamedRoute<T extends Readonly<_RouteRecordBase>> = [
+  T
+] extends [{ name: string; readonly children?: any[] }]
+  ? { [K in T['name']]: unknown } &
+      ([T['children']] extends [Readonly<Array<_RouteRecordBase>>]
+        ? ExtractNamedRoutes<T['children']>
+        : {})
+  : never
 
 export type ExtractNamedRoutes<
-  T extends Array<RouteRecordRaw>
-> = T extends Array<infer R>
-  ? [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<Array<_RouteRecordBase>> | undefined
+> = T extends Readonly<Array<infer R>>
+  ? // ? [R] extends [{ name: string /*params?: infer Params*/ }]
+    [R] extends [_RouteRecordBase]
+    ? ExtractNamedRoute<R>
+    : {}
   : 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<typeof routes>
+
+// 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<typeof routes>
+
 //   export type ExtractNamedRoutes<
 //   T extends Array<RouteRecordRaw> | Readonly<Array<RouteRecordRaw>>
 // > = T extends Array<infer R>
@@ -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<typeof r>
+// declare const x: ExtractNamedRoutes<typeof r>
index 93cc9541f34222e6db1dd6aa10e386baaf989bf7..8ecc91bac1542b5a085bfc7c99ebf78a5ed66826 100644 (file)
@@ -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<typeof routes>
 
@@ -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',
 })