]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
refactor: use type safe isArray
authorEduardo San Martin Morote <posva13@gmail.com>
Mon, 16 May 2022 13:22:43 +0000 (15:22 +0200)
committerEduardo San Martin Morote <posva@users.noreply.github.com>
Thu, 30 Jun 2022 07:59:00 +0000 (09:59 +0200)
src/RouterLink.ts
src/RouterView.ts
src/devtools.ts
src/location.ts
src/matcher/pathParserRanker.ts
src/query.ts
src/router.ts
src/utils/index.ts

index 79bad41619afae6b9a10702023cf96dd1cd30971..9e1872212d86343eddbf5db8af155efeb938ac45 100644 (file)
@@ -36,7 +36,7 @@ import { isSameRouteLocationParams, isSameRouteRecord } from './location'
 import { routerKey, routeLocationKey } from './injectionSymbols'
 import { RouteRecord } from './matcher/types'
 import { NavigationFailure } from './errors'
-import { isBrowser, noop } from './utils'
+import { isArray, isBrowser, noop } from './utils'
 import { RouterTyped } from './typedRouter'
 
 export interface RouterLinkOptions {
@@ -303,7 +303,7 @@ function includesParams(
       if (innerValue !== outerValue) return false
     } else {
       if (
-        !Array.isArray(outerValue) ||
+        !isArray(outerValue) ||
         outerValue.length !== innerValue.length ||
         innerValue.some((value, i) => value !== outerValue[i])
       )
index 4c2eca482c0f48a6762e09364c9ce683a67c24bf..985e29fb60d30d096b036ddb10f3de5e70b46f55 100644 (file)
@@ -26,7 +26,7 @@ import {
   viewDepthKey,
   routerViewLocationKey,
 } from './injectionSymbols'
-import { assign, isBrowser } from './utils'
+import { assign, isArray, isBrowser } from './utils'
 import { warn } from './warning'
 import { isSameRouteRecord } from './location'
 
@@ -182,7 +182,7 @@ export const RouterViewImpl = /*#__PURE__*/ defineComponent({
           meta: matchedRoute.meta,
         }
 
-        const internalInstances = Array.isArray(component.ref)
+        const internalInstances = isArray(component.ref)
           ? component.ref.map(r => r.i)
           : [component.ref.i]
 
index 7aac3d8ae72231bda240dfe72b825e835239d4bc..a7d4f4e143e2e4b2d1182841bb7d37abb40d2977 100644 (file)
@@ -17,7 +17,7 @@ import { Router } from './router'
 import { UseLinkDevtoolsContext } from './RouterLink'
 import { RouterViewDevtoolsContext } from './RouterView'
 import { RouteLocationNormalized } from './types'
-import { assign } from './utils'
+import { assign, isArray } from './utils'
 
 function formatRouteLocation(
   routeLocation: RouteLocationNormalized,
@@ -101,7 +101,7 @@ export function addDevtools(app: App, router: Router, matcher: RouterMatcher) {
           })
         }
         // if multiple useLink are used
-        if (Array.isArray(componentInstance.__vrl_devtools)) {
+        if (isArray(componentInstance.__vrl_devtools)) {
           componentInstance.__devtoolsApi = api
           ;(
             componentInstance.__vrl_devtools as UseLinkDevtoolsContext[]
index 78efa330211e0f294ad2b911bcbabdc5d72a0e76..8ba3caa6f80facc473c99e3835db906fa60e48f0 100644 (file)
@@ -6,6 +6,7 @@ import {
 } from './types'
 import { RouteRecord } from './matcher/types'
 import { warn } from './warning'
+import { isArray } from './utils'
 
 /**
  * Location object returned by {@link `parseURL`}.
@@ -168,9 +169,9 @@ function isSameRouteLocationParamsValue(
   a: RouteParamValue | readonly RouteParamValue[],
   b: RouteParamValue | readonly RouteParamValue[]
 ): boolean {
-  return Array.isArray(a)
+  return isArray(a)
     ? isEquivalentArray(a, b)
-    : Array.isArray(b)
+    : isArray(b)
     ? isEquivalentArray(b, a)
     : a === b
 }
@@ -182,8 +183,8 @@ function isSameRouteLocationParamsValue(
  * @param a - array of values
  * @param b - array of values or a single value
  */
-function isEquivalentArray<T>(a: T[], b: T[] | T): boolean {
-  return Array.isArray(b)
+function isEquivalentArray<T>(a: readonly T[], b: readonly T[] | T): boolean {
+  return isArray(b)
     ? a.length === b.length && a.every((value, i) => value === b[i])
     : a.length === 1 && a[0] === b
 }
index 57dd088473e23ab6c9a81f8613fb3683afba9f99..605d23266a0963b31d0183ce9210e04b2d89e527 100644 (file)
@@ -1,5 +1,5 @@
 import { Token, TokenType } from './pathTokenizer'
-import { assign } from '../utils'
+import { assign, isArray } from '../utils'
 
 export type PathParams = Record<string, string | readonly string[]>
 
@@ -244,11 +244,13 @@ export function tokensToParser(
           const param: string | readonly string[] =
             value in params ? params[value] : ''
 
-          if (Array.isArray(param) && !repeatable)
+          if (isArray(param) && !repeatable) {
             throw new Error(
               `Provided param "${value}" is an array but it is not repeatable (* or + modifiers)`
             )
-          const text: string = Array.isArray(param)
+          }
+
+          const text: string = isArray(param)
             ? (param as string[]).join('/')
             : (param as string)
           if (!text) {
index 21142e1c23bc3a628dd3279d869f717f35f53097..d315a84b8f17d01ae00bd068f58aa1b60720a622 100644 (file)
@@ -1,4 +1,5 @@
 import { decode, encodeQueryKey, encodeQueryValue, PLUS_RE } from './encoding'
+import { isArray } from './utils'
 
 /**
  * Possible values in normalized {@link LocationQuery}. `null` renders the query
@@ -27,7 +28,7 @@ export type LocationQueryValueRaw = LocationQueryValue | number | undefined
  */
 export type LocationQuery = Record<
   string,
-  LocationQueryValue | LocationQueryValue[]
+  LocationQueryValue | readonly LocationQueryValue[]
 >
 /**
  * Loose {@link LocationQuery} object that can be passed to functions like
@@ -38,7 +39,7 @@ export type LocationQuery = Record<
  */
 export type LocationQueryRaw = Record<
   string | number,
-  LocationQueryValueRaw | LocationQueryValueRaw[]
+  LocationQueryValueRaw | readonly LocationQueryValueRaw[]
 >
 
 /**
@@ -68,10 +69,11 @@ export function parseQuery(search: string): LocationQuery {
     if (key in query) {
       // an extra variable for ts types
       let currentValue = query[key]
-      if (!Array.isArray(currentValue)) {
+      if (!isArray(currentValue)) {
         currentValue = query[key] = [currentValue]
       }
-      currentValue.push(value)
+      // we force the modification
+      ;(currentValue as LocationQueryValue[]).push(value)
     } else {
       query[key] = value
     }
@@ -101,7 +103,7 @@ export function stringifyQuery(query: LocationQueryRaw): string {
       continue
     }
     // keep null values
-    const values: LocationQueryValueRaw[] = Array.isArray(value)
+    const values: LocationQueryValueRaw[] = isArray(value)
       ? value.map(v => v && encodeQueryValue(v))
       : [value && encodeQueryValue(value)]
 
@@ -135,7 +137,7 @@ export function normalizeQuery(
   for (const key in query) {
     const value = query[key]
     if (value !== undefined) {
-      normalizedQuery[key] = Array.isArray(value)
+      normalizedQuery[key] = isArray(value)
         ? value.map(v => (v == null ? null : '' + v))
         : value == null
         ? value
index dbe6b308cf56b8caab3dbcb7fbed0f2975b6dcf1..7f0f9d1f958eba0a4ac3668ef69a28247d2d1240 100644 (file)
@@ -34,7 +34,7 @@ import {
   NavigationRedirectError,
   isNavigationFailure,
 } from './errors'
-import { applyToParams, isBrowser, assign, noop } from './utils'
+import { applyToParams, isBrowser, assign, noop, isArray } from './utils'
 import { useCallbacks } from './utils/callbacks'
 import { encodeParam, decode, encodeHash } from './encoding'
 import {
@@ -859,7 +859,7 @@ export function createRouter<Options extends RouterOptions>(
           for (const record of to.matched) {
             // do not trigger beforeEnter on reused views
             if (record.beforeEnter && !from.matched.includes(record)) {
-              if (Array.isArray(record.beforeEnter)) {
+              if (isArray(record.beforeEnter)) {
                 for (const beforeEnter of record.beforeEnter)
                   guards.push(guardToPromiseFn(beforeEnter, to, from))
               } else {
index 1e5576af72804cb05ddb82b96a6807615f6682f9..af90cb5cefed42ec78fed89e6371ea7846e46a45 100644 (file)
@@ -21,7 +21,7 @@ export function applyToParams(
 
   for (const key in params) {
     const value = params[key]
-    newParams[key] = Array.isArray(value)
+    newParams[key] = isArray(value)
       ? value.map(fn)
       : fn(value as Exclude<RouteParamValueRaw, any[]>)
   }
@@ -30,3 +30,10 @@ export function applyToParams(
 }
 
 export const noop = () => {}
+
+/**
+ * Typesafe alternative to Array.isArray
+ * https://github.com/microsoft/TypeScript/pull/48228
+ */
+export const isArray: (arg: ArrayLike<any> | any) => arg is ReadonlyArray<any> =
+  Array.isArray