From: Eduardo San Martin Morote Date: Wed, 15 Jun 2022 16:37:12 +0000 (+0200) Subject: feat: add typed router link X-Git-Tag: v4.1.0~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d02d19f07985c7d6edf167eb59c3f18273b91ec0;p=thirdparty%2Fvuejs%2Frouter.git feat: add typed router link --- diff --git a/packages/playground/src/router.ts b/packages/playground/src/router.ts index ca88c525..836edad6 100644 --- a/packages/playground/src/router.ts +++ b/packages/playground/src/router.ts @@ -1,4 +1,5 @@ import { createRouter, createWebHistory, RouterView } from 'vue-router' +import type { RouterLinkTyped } from 'vue-router' import Home from './views/Home.vue' import Nested from './views/Nested.vue' import NestedWithId from './views/NestedWithId.vue' @@ -189,6 +190,12 @@ declare module 'vue-router' { } } +declare module 'vue' { + interface GlobalComponents { + RouterLink: RouterLinkTyped + } +} + const delay = (t: number) => new Promise(resolve => setTimeout(resolve, t)) // remove trailing slashes diff --git a/packages/router/src/RouterLink.ts b/packages/router/src/RouterLink.ts index bc28001f..b82f75e2 100644 --- a/packages/router/src/RouterLink.ts +++ b/packages/router/src/RouterLink.ts @@ -31,18 +31,25 @@ import { VueUseOptions, RouteLocation, RouteLocationNormalized, + RouteLocationPathRaw, + RouteLocationString, + RouteLocationNamedRaw, } from './types' import { isSameRouteLocationParams, isSameRouteRecord } from './location' import { routerKey, routeLocationKey } from './injectionSymbols' import { RouteRecord } from './matcher/types' import { NavigationFailure } from './errors' import { isArray, isBrowser, noop } from './utils' +import type { Router } from './router' +import { RouteNamedMap, RouteStaticPathMap } from './types/named' -export interface RouterLinkOptions { +export interface RouterLinkOptions< + Routes extends RouteLocationRaw = RouteLocationRaw +> { /** * Route Location the link should navigate to when clicked on. */ - to: RouteLocationRaw + to: Routes /** * Calls `router.replace` instead of `router.push`. */ @@ -50,7 +57,9 @@ export interface RouterLinkOptions { // TODO: refactor using extra options allowed in router.push. Needs RFC } -export interface RouterLinkProps extends RouterLinkOptions { +export interface RouterLinkProps< + Routes extends RouteLocationRaw = RouteLocationRaw +> extends RouterLinkOptions { /** * Whether RouterLink should not wrap its content in an `a` tag. Useful when * using `v-slot` to create a custom RouterLink @@ -251,12 +260,18 @@ export const RouterLinkImpl = /*#__PURE__*/ defineComponent({ /** * Component to render a link that triggers a navigation on click. */ -export const RouterLink = RouterLinkImpl as unknown as { +export const RouterLink = RouterLinkImpl as unknown as RouterLinkTyped + +export interface RouterLinkTyped { new (): { $props: AllowedComponentProps & ComponentCustomProps & VNodeProps & - RouterLinkProps + RouterLinkProps< + | RouteLocationNamedRaw> + | RouteLocationString> + | RouteLocationPathRaw> + > $slots: { default: (arg: UnwrapRef>) => VNode[] diff --git a/packages/router/src/index.ts b/packages/router/src/index.ts index 0502e1ee..c93fe522 100644 --- a/packages/router/src/index.ts +++ b/packages/router/src/index.ts @@ -99,7 +99,11 @@ export { loadRouteLocation, } from './navigationGuards' export { RouterLink, useLink } from './RouterLink' -export type { RouterLinkProps, UseLinkOptions } from './RouterLink' +export type { + RouterLinkProps, + UseLinkOptions, + RouterLinkTyped, +} from './RouterLink' export { RouterView } from './RouterView' export type { RouterViewProps } from './RouterView'