From ea77ad95b0b0c1173d4567ea4e1a70384c56a5a4 Mon Sep 17 00:00:00 2001 From: rukipomoi Date: Tue, 9 Sep 2025 16:00:49 +0400 Subject: [PATCH 1/3] fix(routerlink): allow event handlers under strictTemplates (fix #2484) --- packages/router/src/RouterLink.ts | 19 ++++++++++++++----- .../router/test-dts/components.test-d.tsx | 11 +++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/router/src/RouterLink.ts b/packages/router/src/RouterLink.ts index e5b5d9d62..5193436c9 100644 --- a/packages/router/src/RouterLink.ts +++ b/packages/router/src/RouterLink.ts @@ -26,6 +26,7 @@ import { // @ts-ignore ComponentOptionsMixin, MaybeRef, + AnchorHTMLAttributes, } from 'vue' import { isSameRouteLocationParams, isSameRouteRecord } from './location' import { routerKey, routeLocationKey } from './injectionSymbols' @@ -365,12 +366,20 @@ export const RouterLink: _RouterLinkI = RouterLinkImpl as any * * @internal */ +type LinkAnchorAttrs = Omit + +type _BaseRouterLinkProps = AllowedComponentProps & + ComponentCustomProps & + VNodeProps & + RouterLinkProps + +type RouterLinkTypedProps = C extends true + ? _BaseRouterLinkProps & { custom: true } + : _BaseRouterLinkProps & { custom?: false | undefined } & LinkAnchorAttrs + export interface _RouterLinkI { - new (): { - $props: AllowedComponentProps & - ComponentCustomProps & - VNodeProps & - RouterLinkProps + new (): { + $props: RouterLinkTypedProps $slots: { default?: ({ diff --git a/packages/router/test-dts/components.test-d.tsx b/packages/router/test-dts/components.test-d.tsx index 07c270520..ac96ec082 100644 --- a/packages/router/test-dts/components.test-d.tsx +++ b/packages/router/test-dts/components.test-d.tsx @@ -27,6 +27,17 @@ describe('Components', () => { expectTypeOf() expectTypeOf() expectTypeOf() + // event handlers and anchor attrs are allowed when not custom + expectTypeOf( + {}} onClick={() => {}} /> + ) + expectTypeOf( + + ) + // @ts-expect-error: href is intentionally omitted + expectError() + // @ts-expect-error: onFocus should not be allowed with custom + expectError( {}} />) // RouterView expectTypeOf() From 9da13d8d8b9d62ef276c5807f9bb28c2e76ec9ee Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Wed, 8 Oct 2025 16:10:15 +0200 Subject: [PATCH 2/3] refactor: simplify --- packages/router/src/RouterLink.ts | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/router/src/RouterLink.ts b/packages/router/src/RouterLink.ts index 5193436c9..d1d0a2a8c 100644 --- a/packages/router/src/RouterLink.ts +++ b/packages/router/src/RouterLink.ts @@ -361,25 +361,33 @@ export const RouterLinkImpl = /*#__PURE__*/ defineComponent({ export const RouterLink: _RouterLinkI = RouterLinkImpl as any /** - * Typed version of the `RouterLink` component. Its generic defaults to the typed router, so it can be inferred - * automatically for JSX. - * * @internal */ -type LinkAnchorAttrs = Omit - type _BaseRouterLinkProps = AllowedComponentProps & ComponentCustomProps & VNodeProps & RouterLinkProps -type RouterLinkTypedProps = C extends true - ? _BaseRouterLinkProps & { custom: true } - : _BaseRouterLinkProps & { custom?: false | undefined } & LinkAnchorAttrs +/** + * @internal + */ +type RouterLinkTypedProps = + Custom extends true + ? _BaseRouterLinkProps & { custom: true } + : _BaseRouterLinkProps & { custom?: false | undefined } & Omit< + AnchorHTMLAttributes, + 'href' + > +/** + * Typed version of the `RouterLink` component. Its generic defaults to the typed router, so it can be inferred + * automatically for JSX. + * + * @internal + */ export interface _RouterLinkI { - new (): { - $props: RouterLinkTypedProps + new (): { + $props: RouterLinkTypedProps $slots: { default?: ({ From b0ac3940e8f5513c9206a920bb25ba294f98ce86 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Wed, 8 Oct 2025 16:12:14 +0200 Subject: [PATCH 3/3] refactor: more --- packages/router/src/RouterLink.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/router/src/RouterLink.ts b/packages/router/src/RouterLink.ts index d1d0a2a8c..b76d47900 100644 --- a/packages/router/src/RouterLink.ts +++ b/packages/router/src/RouterLink.ts @@ -363,7 +363,7 @@ export const RouterLink: _RouterLinkI = RouterLinkImpl as any /** * @internal */ -type _BaseRouterLinkProps = AllowedComponentProps & +type _RouterLinkPropsTypedBase = AllowedComponentProps & ComponentCustomProps & VNodeProps & RouterLinkProps @@ -371,10 +371,10 @@ type _BaseRouterLinkProps = AllowedComponentProps & /** * @internal */ -type RouterLinkTypedProps = +type RouterLinkPropsTyped = Custom extends true - ? _BaseRouterLinkProps & { custom: true } - : _BaseRouterLinkProps & { custom?: false | undefined } & Omit< + ? _RouterLinkPropsTypedBase & { custom: true } + : _RouterLinkPropsTypedBase & { custom?: false | undefined } & Omit< AnchorHTMLAttributes, 'href' > @@ -387,7 +387,7 @@ type RouterLinkTypedProps = */ export interface _RouterLinkI { new (): { - $props: RouterLinkTypedProps + $props: RouterLinkPropsTyped $slots: { default?: ({