]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
feat: allow symbols as route record name
authorEduardo San Martin Morote <posva13@gmail.com>
Tue, 7 Apr 2020 10:40:13 +0000 (12:40 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Tue, 7 Apr 2020 10:40:13 +0000 (12:40 +0200)
src/matcher/index.ts
src/router.ts
src/types/index.ts
src/types/type-guards.ts

index 6fcb4ca4a9a69f71d4fc054702eb2455c97dab73..d9da01683a2d64e2a96ebd93ff7bac3ac867caf9 100644 (file)
@@ -1,4 +1,10 @@
-import { RouteRecordRaw, MatcherLocationRaw, MatcherLocation } from '../types'
+import {
+  RouteRecordRaw,
+  MatcherLocationRaw,
+  MatcherLocation,
+  isRouteName,
+  RouteRecordName,
+} from '../types'
 import { createRouterError, ErrorTypes, MatcherError } from '../errors'
 import { createRouteRecordMatcher, RouteRecordMatcher } from './path-matcher'
 import { RouteRecordRedirect, RouteRecordNormalized } from './types'
@@ -14,12 +20,10 @@ interface RouterMatcher {
   addRoute: (record: RouteRecordRaw, parent?: RouteRecordMatcher) => () => void
   removeRoute: {
     (matcher: RouteRecordMatcher): void
-    (name: Required<RouteRecordRaw>['name']): void
+    (name: RouteRecordName): void
   }
   getRoutes: () => RouteRecordMatcher[]
-  getRecordMatcher: (
-    name: Required<RouteRecordRaw>['name']
-  ) => RouteRecordMatcher | undefined
+  getRecordMatcher: (name: RouteRecordName) => RouteRecordMatcher | undefined
   resolve: (
     location: MatcherLocationRaw,
     currentLocation: MatcherLocation
@@ -32,9 +36,9 @@ export function createRouterMatcher(
 ): RouterMatcher {
   // normalized ordered array of matchers
   const matchers: RouteRecordMatcher[] = []
-  const matcherMap = new Map<string | symbol, RouteRecordMatcher>()
+  const matcherMap = new Map<RouteRecordName, RouteRecordMatcher>()
 
-  function getRecordMatcher(name: string) {
+  function getRecordMatcher(name: RouteRecordName) {
     return matcherMap.get(name)
   }
 
@@ -130,8 +134,8 @@ export function createRouterMatcher(
       : noop
   }
 
-  function removeRoute(matcherRef: string | RouteRecordMatcher) {
-    if (typeof matcherRef === 'string') {
+  function removeRoute(matcherRef: RouteRecordName | RouteRecordMatcher) {
+    if (isRouteName(matcherRef)) {
       const matcher = matcherMap.get(matcherRef)
       if (matcher) {
         matcherMap.delete(matcherRef)
index e06595ecee728f9369de248d0aeb463251a061b3..be9b9a14bd511934492cc9f375025f243c9aa10f 100644 (file)
@@ -10,6 +10,8 @@ import {
   MatcherLocation,
   RouteLocationNormalizedLoaded,
   RouteLocation,
+  RouteRecordName,
+  isRouteName,
 } from './types'
 import { RouterHistory, HistoryState } from './history/common'
 import {
@@ -83,9 +85,10 @@ export interface Router {
   history: RouterHistory
   currentRoute: Ref<RouteLocationNormalizedLoaded>
 
-  addRoute(parentName: string, route: RouteRecordRaw): () => void
+  addRoute(parentName: RouteRecordName, route: RouteRecordRaw): () => void
   addRoute(route: RouteRecordRaw): () => void
-  removeRoute(name: string): void
+  removeRoute(name: RouteRecordName): void
+  // TODO: hasRoute()
   getRoutes(): RouteRecord[]
 
   resolve(to: RouteLocationRaw): RouteLocation
@@ -132,12 +135,12 @@ export function createRouter({
   const decodeParams = applyToParams.bind(null, decode)
 
   function addRoute(
-    parentOrRoute: string | RouteRecordRaw,
+    parentOrRoute: RouteRecordName | RouteRecordRaw,
     route?: RouteRecordRaw
   ) {
     let parent: Parameters<typeof matcher['addRoute']>[1] | undefined
     let record: RouteRecordRaw
-    if (typeof parentOrRoute === 'string') {
+    if (isRouteName(parentOrRoute)) {
       parent = matcher.getRecordMatcher(parentOrRoute)
       record = route!
     } else {
@@ -147,13 +150,13 @@ export function createRouter({
     return matcher.addRoute(record, parent)
   }
 
-  function removeRoute(name: string) {
+  function removeRoute(name: RouteRecordName) {
     let recordMatcher = matcher.getRecordMatcher(name)
     if (recordMatcher) {
       matcher.removeRoute(recordMatcher)
     } else if (__DEV__) {
       // TODO: adapt if we allow Symbol as a name
-      warn(`Cannot remove non-existent route "${name}"`)
+      warn(`Cannot remove non-existent route "${String(name)}"`)
     }
   }
 
index 043b63acc1cc824e797488c6e79eca5f1127de8b..e1ce660c740bf83925cf1a9f145f9249e12c5f9a 100644 (file)
@@ -43,7 +43,7 @@ export interface LocationAsPath {
 }
 
 export interface LocationAsName {
-  name: string
+  name: RouteRecordName
   params?: RouteParamsRaw
 }
 
@@ -90,7 +90,7 @@ export interface _RouteLocationBase {
   fullPath: string
   query: LocationQuery
   hash: string
-  name: string | null | undefined
+  name: RouteRecordName | null | undefined
   params: RouteParams
   // TODO: make it an array?
   redirectedFrom: RouteLocation | undefined
@@ -171,6 +171,8 @@ export interface RouteComponentInterface {
 export type RouteComponent = ComponentOptions & RouteComponentInterface
 export type RawRouteComponent = RouteComponent | Lazy<RouteComponent>
 
+export type RouteRecordName = string | symbol
+
 // TODO: could this be moved to matcher?
 /**
  * Common properties among all kind of {@link RouteRecordRaw}
@@ -190,7 +192,7 @@ export interface _RouteRecordBase {
   /**
    * Name for the route record.
    */
-  name?: string
+  name?: RouteRecordName
   /**
    * Allow passing down params as props to the component rendered by `router-view`.
    */
index a00d4dbfb910a6a481b415f0df562de37429bb2b..782ef08c00ad4be298a572fc3753d346448d9be9 100644 (file)
@@ -1,5 +1,9 @@
-import { RouteLocationRaw } from './index'
+import { RouteLocationRaw, RouteRecordName } from './index'
 
 export function isRouteLocation(route: any): route is RouteLocationRaw {
   return typeof route === 'string' || (route && typeof route === 'object')
 }
+
+export function isRouteName(name: any): name is RouteRecordName {
+  return typeof name === 'string' || typeof name === 'symbol'
+}