]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
fix(types): remove many @ts-ignore
authorEduardo San Martin Morote <posva13@gmail.com>
Mon, 1 Jul 2019 15:49:51 +0000 (17:49 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Mon, 1 Jul 2019 15:49:51 +0000 (17:49 +0200)
__tests__/errors.spec.js
__tests__/history/abstract.spec.js
__tests__/matcher.spec.js
__tests__/router-view.spec.js
__tests__/utils.ts
explorations/html5.ts
src/components/Link.ts
src/components/View.ts
src/history/html5.ts
src/index.ts
src/matcher.ts

index c4cdc90002f4f1cc5c74df1e1cd6757b5250d7f9..7d35b5172ea7d56005828ad420881c8d97e02b19 100644 (file)
@@ -32,13 +32,14 @@ const routes = [
 
 const onError = jest.fn()
 function createRouter() {
+  const history = new AbstractHistory()
   const router = new Router({
-    history: new AbstractHistory(),
+    history,
     routes,
   })
 
   router.onError(onError)
-  return router
+  return { router, history }
 }
 
 describe('Errors', () => {
@@ -47,7 +48,7 @@ describe('Errors', () => {
   })
 
   it('triggers onError when navigation is aborted', async () => {
-    const router = createRouter()
+    const { router } = createRouter()
     router.beforeEach((to, from, next) => {
       next(false)
     })
@@ -61,7 +62,7 @@ describe('Errors', () => {
   })
 
   it('triggers erros caused by new navigations of a next(redirect) trigered by history', async () => {
-    const router = createRouter()
+    const { router, history } = createRouter()
     await router.push('/p/0')
     await router.push('/p/other')
 
@@ -71,8 +72,7 @@ describe('Errors', () => {
       else next({ name: 'Param', params: { p: '' + p } })
     })
 
-    // @ts-ignore
-    router.history.back()
+    history.back()
     await tick()
 
     expect(onError).toHaveBeenCalledTimes(2)
index b32fb881fe81ed591fe12a249584fe69e55d51ca..259e96e7a94e1f525ac850b979cdb9221d2d3904 100644 (file)
@@ -223,10 +223,10 @@ describe('Abstract/in memory history', () => {
     const history = new AbstractHistory()
     const spy = jest.fn()
     history.listen(spy)
-    // @ts-ignore
+    // @ts-ignore we need to check internals here
     expect(history.listeners).toHaveLength(1)
     history.destroy()
-    // @ts-ignore
+    // @ts-ignore we need to check internals here
     expect(history.listeners).toHaveLength(0)
   })
 
index d7102ffa2e1c702a0eec580f4a2abeb217d427fd..7dae8e822fab31b5f0bcbff2c176cc98c605522e 100644 (file)
@@ -8,6 +8,7 @@ const { normalizeRouteRecord } = require('./utils')
 const component = null
 
 /** @typedef {import('../src/types').RouteRecord} RouteRecord */
+/** @typedef {import('../src/types').RouteComponent} RouteComponent */
 /** @typedef {import('../src/types').MatchedRouteRecord} MatchedRouteRecord */
 /** @typedef {import('../src/types').MatcherLocation} MatcherLocation */
 /** @typedef {import('../src/types').MatcherLocationRedirect} MatcherLocationRedirect */
@@ -20,7 +21,7 @@ describe('Router Matcher', () => {
      * @param {RouteRecord | RouteRecord[]} record Record or records we are testing the matcher against
      * @param {MatcherLocation} location location we want to reolve against
      * @param {Partial<MatcherLocationNormalized & { component: any }>} resolved Expected resolved location given by the matcher
-     * @param {MatcherLocationNormalized} [start] Optional currentLocation used when resolving
+     * @param {MatcherLocationNormalized | (MatcherLocationNormalized & { matched: Array<MatchedRouteRecord | Exclude<RouteRecord, { redirect: any}>> })} [start] Optional currentLocation used when resolving
      */
     function assertRecordMatch(
       record,
@@ -40,8 +41,8 @@ describe('Router Matcher', () => {
       if ('redirect' in record) {
       } else {
         // use one single record
-        // @ts-ignore
-        if (!('matched' in resolved)) resolved.matched = record
+        if (!('matched' in resolved))
+          resolved.matched = record.map(normalizeRouteRecord)
       }
 
       // allows not passing params
@@ -51,22 +52,23 @@ describe('Router Matcher', () => {
         resolved.params = resolved.params || {}
       }
 
-      for (const matched of resolved.matched) {
-        if ('component' in matched) {
-          // @ts-ignore
-          matched.components = { default: matched.component }
-          // @ts-ignore
-          delete matched.component
-        }
+      if (!('matched' in resolved)) resolved.matched = []
+
+      const startCopy = {
+        ...start,
+        matched: start.matched.map(normalizeRouteRecord),
       }
 
+      // make matched non enumerable
+      Object.defineProperty(startCopy, 'matched', { enumerable: false })
+
       const result = matcher.resolve(
         {
           ...targetLocation,
           // override anything provided in location
           ...location,
         },
-        start
+        startCopy
       )
       expect(result).toEqual(resolved)
     }
index 188a9a756226de04476e44eb178c9092e5b0ee21..1c1ea358c7e18e5c5fbf152b2392d26d6893335c 100644 (file)
@@ -35,7 +35,7 @@ describe('RouterView', () => {
    * @param {RouteLocationNormalized} $route
    */
   function factory($route) {
-    // @ts-ignore
+    // @ts-ignore cannot mount functional component?
     const wrapper = mount(RouterView, {
       mocks: { $route },
     })
index c3791dd16b5ce2149e3dc3795062e1cca5dd1ba9..61f72f9abc93a538b50abdf6aef89ec69be45a0a 100644 (file)
@@ -7,6 +7,17 @@ export const tick = () => new Promise(resolve => process.nextTick(resolve))
 
 export const NAVIGATION_TYPES = ['push', 'replace']
 
+declare global {
+  namespace NodeJS {
+    interface Global {
+      window: JSDOM['window']
+      location: JSDOM['window']['location']
+      document: JSDOM['window']['document']
+      before?: Function
+    }
+  }
+}
+
 export function createDom(options?: ConstructorOptions) {
   const dom = new JSDOM(
     `<!DOCTYPE html><html><head></head><body></body></html>`,
@@ -18,11 +29,8 @@ export function createDom(options?: ConstructorOptions) {
     }
   )
 
-  // @ts-ignore
   global.window = dom.window
-  // @ts-ignore
   global.location = dom.window.location
-  // @ts-ignore
   global.document = dom.window.document
 
   return dom
@@ -41,7 +49,6 @@ export const components = {
 // allow using a .jest modifider to skip some tests on mocha
 // specifically, skip component tests as they are a pain to correctly
 // adapt to mocha
-// @ts-ignore
 export const isMocha = () => typeof global.before === 'function'
 
 /**
index 90d21d58b9de9cb0f817dbe1810f6cee1cf6cd8a..27894fc43e815c7fa8f0fc66554a3140dc44b29d 100644 (file)
@@ -5,6 +5,8 @@ import Vue from 'vue'
 declare global {
   interface Window {
     vm: Vue
+    h: HTML5History
+    r: Router
   }
 }
 
@@ -34,8 +36,9 @@ const GuardedWithLeave: RouteComponent = {
   },
 }
 
+const html5History = new HTML5History()
 const router = new Router({
-  history: new HTML5History(),
+  history: html5History,
   routes: [
     { path: '/', component: Home },
     { path: '/users/:id', name: 'user', component: User },
@@ -65,7 +68,11 @@ const router = new Router({
   ],
 })
 
+// for testing purposes
 const r = router
+const h = html5History
+window.h = h
+window.r = r
 
 const delay = (t: number) => new Promise(resolve => setTimeout(resolve, t))
 
@@ -99,14 +106,6 @@ r.beforeEach((to, from, next) => {
   next()
 })
 
-// const h = new HTML5History()
-// @ts-ignore
-const h = r.history
-// @ts-ignore
-window.h = h
-// @ts-ignore
-window.r = r
-
 h.listen((to, from, { direction }) => {
   console.log(`popstate(${direction})`, { to, from })
 })
index 3c29d523f29732d32287894065db96c132ed7be6..184623797f507ec68f450bb440f82b4d32f54cd3 100644 (file)
@@ -1,6 +1,7 @@
 import { Component } from 'vue'
 import { Router } from '../router'
 import { RouteLocationNormalized, RouteLocation } from '../types'
+import { HistoryLocationNormalized } from '../history/base'
 
 const Link: Component = {
   name: 'RouterLink',
@@ -12,33 +13,29 @@ const Link: Component = {
   },
 
   render(h) {
-    // @ts-ignore
+    // @ts-ignore can't get `this`
     const router = this.$router as Router
-    // @ts-ignore
+    // @ts-ignore can't get `this`
     const from = this.$route as RouteLocationNormalized
-    // @ts-ignore
+    // @ts-ignore can't get `this`
     const to = this.to as RouteLocation
-    // @ts-ignore
+    // @ts-ignore can't get `this`
+    const history = router.history
     let url: HistoryLocationNormalized
     let location: RouteLocationNormalized
     // TODO: refactor router code and use its function istead of having a copied version here
     if (typeof to === 'string' || 'path' in to) {
-      // @ts-ignore
-      url = router.history.utils.normalizeLocation(to)
+      url = history.utils.normalizeLocation(to)
       // TODO: should allow a non matching url to allow dynamic routing to work
       location = router.resolveLocation(url, from)
     } else {
       // named or relative route
-      // @ts-ignore
-      const query = router.history.utils.normalizeQuery(
-        to.query ? to.query : {}
-      )
+      const query = history.utils.normalizeQuery(to.query ? to.query : {})
       const hash = to.hash || ''
       // we need to resolve first
       location = router.resolveLocation({ ...to, query, hash }, from)
       // intentionally drop current query and hash
-      // @ts-ignore
-      url = router.history.utils.normalizeLocation({
+      url = history.utils.normalizeLocation({
         query,
         hash,
         ...location,
@@ -75,9 +72,9 @@ function guardEvent(e: MouseEvent) {
   // don't redirect on right click
   if (e.button !== undefined && e.button !== 0) return
   // don't redirect if `target="_blank"`
-  // @ts-ignore
+  // @ts-ignore getAttribute does exist
   if (e.currentTarget && e.currentTarget.getAttribute) {
-    // @ts-ignore
+    // @ts-ignore getAttribute exists
     const target = e.currentTarget.getAttribute('target')
     if (/\b_blank\b/i.test(target)) return
   }
index ee887ec81b4f997b7f23045c02ba0c122d8ef024..7316d8487b941d01183d5cf6a0a92fc9f6d66ab2 100644 (file)
@@ -14,14 +14,13 @@ const View: Component = {
   },
 
   render(_, { children, parent, data, props }) {
-    // used by devtools to display a router-view badge
-    // @ts-ignore
+    // @ts-ignore used by devtools to display a router-view badge
     data.routerView = true
 
     // directly use parent context's createElement() function
     // so that components rendered by router-view can resolve named slots
     const h = parent.$createElement
-    // @ts-ignore
+    // @ts-ignore $route is added by our typings
     const route = parent.$route
 
     // TODO: support nested router-views
index c1ad96a331a7423d2a01c784768d2683171275b8..4f5ffce73b5acbca3b0edd555a1808115f29d444 100644 (file)
@@ -6,7 +6,6 @@ const cs = consola.withTag('html5')
 
 // TODO: implement the mock instead
 /* istanbul ignore next */
-// @ts-ignore
 if (process.env.NODE_ENV === 'test') cs.mockTypes(() => jest.fn())
 
 type PopStateListener = (this: Window, ev: PopStateEvent) => any
index 1fcb1b989bb6de44eef6b71322ef88f9ba327dd3..bfc1bc0ce7e856c073b57224592909d29be05f60 100644 (file)
@@ -9,30 +9,28 @@ import Link from './components/Link'
 const plugin: PluginFunction<void> = Vue => {
   Vue.mixin({
     beforeCreate() {
-      // @ts-ignore
-      if (this.$options.router) {
-        // @ts-ignore
+      if ('router' in this.$options) {
+        // @ts-ignore we are adding this
         this._routerRoot = this
-        // @ts-ignore
-        this._router = this.$options.router as Router
+        // @ts-ignore should be able to be removed once we add the typing
+        const router = this.$options.router as Router
+        // @ts-ignore _router is internal
+        this._router = router
         // this._router.init(this)
         // @ts-ignore
         this._router.app = this
-        // @ts-ignore
+        // @ts-ignore we can use but should not be used by others
         Vue.util.defineReactive(
-          // @ts-ignore
           this,
           '_route',
-          // @ts-ignore
-          this._router.currentRoute
+          router.currentRoute
           // undefined,
           // true
         )
 
-        // @ts-ignore
-        this._router.doInitialNavigation()
+        router.doInitialNavigation()
       } else {
-        // @ts-ignore
+        // @ts-ignore we are adding this
         this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
       }
     },
@@ -50,9 +48,9 @@ const plugin: PluginFunction<void> = Vue => {
     },
   })
 
-  // @ts-ignore
+  // @ts-ignore FIXME: should work
   Vue.component('RouterView', View)
-  // @ts-ignore
+  // @ts-ignore FIXME: should work
   Vue.component('RouterLink', Link)
   // Vue.component('RouterLink', Link)
 
index 8ce1a603c908153d7b0d9281495976c6b67aeae8..6d392889d6f51c4a3f24b751e91de216e8479dda 100644 (file)
@@ -32,7 +32,12 @@ export function normalizeRecord(
 ): NormalizedRouteRecord {
   if ('component' in record) {
     const { component, ...rest } = record
-    // @ts-ignore
+    // @ts-ignore I could do it type safe by copying again rest:
+    // return {
+    //   ...rest,
+    //   components: { default: component }
+    // }
+    // but it's slower
     rest.components = { default: component }
     return rest as NormalizedRouteRecord
   }