]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
feat: support for typescript named routes
authorpikax <carlos@hypermob.co.uk>
Thu, 8 Apr 2021 17:16:20 +0000 (18:16 +0100)
committerEduardo San Martin Morote <posva@users.noreply.github.com>
Thu, 30 Jun 2022 07:59:00 +0000 (09:59 +0200)
src/index.ts
src/router.ts
src/types/index.ts
src/types/named.ts [new file with mode: 0644]
test-dts/namedRoutes.test-d.ts [new file with mode: 0644]

index 7c583a216317289442abaa919cc9aa673b007340..d5975392bc29c63acae9c4076ba2ce403a7e87bc 100644 (file)
@@ -47,6 +47,10 @@ export type {
   RouteLocationMatched,
   RouteLocationOptions,
   RouteRecordRedirectOption,
+  RouteNamedLocation,
+  defineRoutes,
+  NamedLocationMap,
+  ExtractNamedRoutes,
   // route records
   _RouteRecordBase,
   RouteMeta,
index fe511b8da56943b39bfee84b200d2e6ff862aa9b..f731505ad3e37b121532f27883bd94f7435e9392 100644 (file)
@@ -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<NavigationFailure | void | undefined>
+  /**
+   * Programmatically navigate to a new URL by pushing an entry in the history
+   * stack.
+   *
+   * @param to - typed route location
+   */
+  push<T extends keyof NamedLocationMap>(
+    to: RouteNamedLocation<T>
+  ): Promise<NavigationFailure | void | undefined>
+
   /**
    * Programmatically navigate to a new URL by replacing the current entry in
    * the history stack.
index d4709cc117bee3433dedfc3023fc4836ec46ec90..e7e507d0b0f3e038601d7be5619469f11e495334 100644 (file)
@@ -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<T> = () => Promise<T>
 export type Override<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U
 
diff --git a/src/types/named.ts b/src/types/named.ts
new file mode 100644 (file)
index 0000000..c01521a
--- /dev/null
@@ -0,0 +1,63 @@
+import { RouteLocationOptions, RouteRecordRaw } from '.'
+
+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
+  : never
+
+//   export type ExtractNamedRoutes<
+//   T extends Array<RouteRecordRaw> | Readonly<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<infer R>>
+//   ? [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<RouteRecordRaw | Readonly<RouteRecordRaw>>
+>(routes: T): ExtractNamedRoutes<T> {
+  return routes as any
+}
+export interface NamedLocationMap {}
+
+export interface RouteNamedLocation<T extends keyof NamedLocationMap>
+  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<typeof r>
diff --git a/test-dts/namedRoutes.test-d.ts b/test-dts/namedRoutes.test-d.ts
new file mode 100644 (file)
index 0000000..92870cd
--- /dev/null
@@ -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 }
+  }
+}