From: Eduardo San Martin Morote Date: Fri, 6 May 2022 13:20:42 +0000 (+0200) Subject: feat: typing global router X-Git-Tag: v4.1.0~101 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aee8d17b058e259be81572c2342b4c453cd86881;p=thirdparty%2Fvuejs%2Frouter.git feat: typing global router --- diff --git a/playground/router.ts b/playground/router.ts index 45860e86..6a9ccadf 100644 --- a/playground/router.ts +++ b/playground/router.ts @@ -161,7 +161,7 @@ export const router = createRouter({ { path: 'settings', component }, ], }, - ], + ] as const, async scrollBehavior(to, from, savedPosition) { await scrollWaiter.wait() if (savedPosition) { @@ -176,6 +176,12 @@ export const router = createRouter({ }, }) +declare module '../src' { + export interface Config { + Router: typeof router + } +} + const delay = (t: number) => new Promise(resolve => setTimeout(resolve, t)) // remove trailing slashes diff --git a/playground/tsconfig.json b/playground/tsconfig.json index a6d5b8b9..7428cbbb 100644 --- a/playground/tsconfig.json +++ b/playground/tsconfig.json @@ -1,5 +1,5 @@ { - "include": ["*.ts", "api", "../src/global.d.ts", "shim.d.ts"], + "include": ["./**/*.ts", "api", "../src/global.d.ts", "shim.d.ts"], "compilerOptions": { "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, diff --git a/src/RouterLink.ts b/src/RouterLink.ts index 68c6dabb..79bad416 100644 --- a/src/RouterLink.ts +++ b/src/RouterLink.ts @@ -37,12 +37,13 @@ import { routerKey, routeLocationKey } from './injectionSymbols' import { RouteRecord } from './matcher/types' import { NavigationFailure } from './errors' import { isBrowser, noop } from './utils' +import { RouterTyped } from './typedRouter' export interface RouterLinkOptions { /** * Route Location the link should navigate to when clicked on. */ - to: RouteLocationRaw + to: Parameters[0] /** * Calls `router.replace` instead of `router.push`. */ diff --git a/src/globalExtensions.ts b/src/globalExtensions.ts index afbd2097..771d2e0d 100644 --- a/src/globalExtensions.ts +++ b/src/globalExtensions.ts @@ -3,9 +3,9 @@ import { NavigationGuard, RouteLocationNormalizedLoaded, } from './types' -import { Router } from './router' import { RouterView } from './RouterView' import { RouterLink } from './RouterLink' +import { RouterTyped } from './typedRouter' declare module '@vue/runtime-core' { export interface ComponentCustomOptions { @@ -55,7 +55,7 @@ declare module '@vue/runtime-core' { /** * {@link Router} instance used by the application. */ - $router: Router + $router: RouterTyped } export interface GlobalComponents { diff --git a/src/injectionSymbols.ts b/src/injectionSymbols.ts index 4114db88..e04ef294 100644 --- a/src/injectionSymbols.ts +++ b/src/injectionSymbols.ts @@ -1,7 +1,7 @@ import { InjectionKey, ComputedRef, Ref } from 'vue' import { RouteLocationNormalizedLoaded } from './types' -import { Router } from './router' import { RouteRecordNormalized } from './matcher/types' +import { RouterTyped } from './typedRouter' /** * RouteRecord being rendered by the closest ancestor Router View. Used for @@ -30,7 +30,9 @@ export const viewDepthKey = Symbol( * * @internal */ -export const routerKey = Symbol(__DEV__ ? 'router' : '') as InjectionKey +export const routerKey = Symbol( + __DEV__ ? 'router' : '' +) as InjectionKey /** * Allows overriding the current route returned by `useRoute` in tests. rl diff --git a/src/types/index.ts b/src/types/index.ts index d0c48bf6..268eecfc 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -79,7 +79,7 @@ export interface LocationAsRelativeRaw< } // this one didn't work 🤔 -// export type _LocationAsRelativeRaw< +// export type LocationAsRelativeRaw< // RouteMap extends RouteNamedMapGeneric = RouteNamedMapGeneric // > = { // [N in keyof RouteMap]: { diff --git a/src/useApi.ts b/src/useApi.ts index 9bf57853..c62ed0c0 100644 --- a/src/useApi.ts +++ b/src/useApi.ts @@ -1,13 +1,13 @@ import { inject } from 'vue' import { routerKey, routeLocationKey } from './injectionSymbols' -import { Router } from './router' +import { RouterTyped } from './typedRouter' import { RouteLocationNormalizedLoaded } from './types' /** * Returns the router instance. Equivalent to using `$router` inside * templates. */ -export function useRouter(): Router { +export function useRouter(): RouterTyped { return inject(routerKey)! } diff --git a/test-dts/namedRoutes.test-d.ts b/test-dts/namedRoutes.test-d.ts index 128b2c8d..7a21c84b 100644 --- a/test-dts/namedRoutes.test-d.ts +++ b/test-dts/namedRoutes.test-d.ts @@ -7,6 +7,7 @@ import { RouterTyped, RouteLocationRaw, JoinPath, + useRouter, } from './index' import { DefineComponent } from 'vue' @@ -82,11 +83,16 @@ for (const method of methods) { r2[method]({ params: { a: 2 } }) r2[method]({ params: {} }) r2[method]({ params: { opt: 'hey' } }) + + // routes with no params + r2[method]({ name: 'nested' }) + r2[method]({ name: 'nested', params: {} }) // FIXME: is it possible to support this version // // @ts-expect-error: does not accept any params // r2[method]({ name: 'nested', params: { eo: 'true' } }) } +// still allow generics to be passed for convenience r2.push({} as unknown as RouteLocationRaw) r2.replace({} as unknown as RouteLocationRaw) @@ -144,11 +150,7 @@ declare module '../dist/vue-router' { } } -function getTypedRouter(): RouterTyped { - return {} as any -} - -const typedRouter = getTypedRouter() +const typedRouter = useRouter() // this one is true if we comment out the line with Router: typeof r2 // expectType(typedRouter) expectType(typedRouter)