]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
fixed it
authorpikax <carlos@hypermob.co.uk>
Fri, 9 Apr 2021 15:22:36 +0000 (16:22 +0100)
committerEduardo San Martin Morote <posva@users.noreply.github.com>
Thu, 30 Jun 2022 07:59:00 +0000 (09:59 +0200)
src/types/named.ts

index c478605d020ed2191ce2e35cdf5c23a0cbe4ad17..c2ea5b54d195e7a365077edfdcd157d330e69929 100644 (file)
 import { RouteRecordRaw, _RouteRecordBase } from '.'
 
+type OptionalPropertyNames<T> = {
+  [K in keyof T]-?: {} extends { [P in K]: T[K] } ? K : never
+}[keyof T]
+
+type SpreadProperties<L, R, K extends keyof L & keyof R> = {
+  [P in K]: L[P] | Exclude<R[P], undefined>
+}
+
+type Id<T> = T extends infer U ? { [K in keyof U]: U[K] } : never
+
+type SpreadTwo<L, R> = Id<
+  Pick<L, Exclude<keyof L, keyof R>> &
+    Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>> &
+    Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>> &
+    SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>
+>
+
+type Spread<A extends readonly [...any]> = A extends [infer L, ...infer R]
+  ? SpreadTwo<L, Spread<R>>
+  : unknown
+
 export type ExtractNamedRoutes<T> = [T] extends [ReadonlyArray<infer U>]
-  ? ExtractNamedRoutes<U>
+  ? ExtractNamedRoutes<NamedRoutes<U>>
   : ([T] extends [{ name: string }] ? { [K in T['name']]: unknown } : {}) &
       ([T] extends [{ children?: undefined | unknown | any }]
-        ? ExtractNamedRoutes<T['children']>
+        ? T['children'] extends undefined
+          ? {}
+          : ExtractNamedRoutes<T['children']>
         : {})
 
+type RouteFiller<T> = T extends { name: string; children: any }
+  ? T
+  : T extends { name: string }
+  ? T & { children: never[] }
+  : T extends { children: any }
+  ? T & { name: '' }
+  : { name: ''; children: never }
+
+export type NamedRoutes<T> = RouteFiller<T>
+
+// declare const xxx: NamedRoutes<
+//   | {
+//       name: 'LOL'
+//     }
+//   | { name: 'xxx' }
+//   | { children: {} }
+// >
+// xxx.name
+
+declare const typed: ExtractNamedRoutes<
+  [
+    {
+      path: 'my-path'
+      name: 'test'
+      // children must be declared :(
+      // children: []
+    },
+    {
+      path: 'my-path'
+      name: 'my-other-path'
+      // children must be declared :(
+      // children: []
+    },
+    {
+      path: 'random'
+      name: 'tt'
+      children: [
+        {
+          path: 'random-child'
+          name: 'random-child'
+          // children: []
+        }
+      ]
+    },
+    {
+      name: '1'
+      children: [
+        {
+          name: '2'
+          children: [{ name: '3'; children: [{ name: '4' }] }]
+        }
+      ]
+    }
+  ]
+>
+
+typed['my-other-path']
+typed['random-child']
+typed.test
+typed.tt
+typed[1]
+typed[2]
+typed[3]
+typed[4]
+
 export function defineRoutes<
   T extends Array<RouteRecordRaw | Readonly<RouteRecordRaw>>
 >(routes: T): ExtractNamedRoutes<T> {