]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
fix(routerlink): allow event handlers under strictTemplates (fix #2484) (#2548)
authorVladimir <Rukipomoi@gmail.com>
Wed, 8 Oct 2025 14:18:50 +0000 (18:18 +0400)
committerGitHub <noreply@github.com>
Wed, 8 Oct 2025 14:18:50 +0000 (16:18 +0200)
Co-authored-by: Eduardo San Martin Morote <posva13@gmail.com>
packages/router/src/RouterLink.ts
packages/router/test-dts/components.test-d.tsx

index e5b5d9d6200d8dbf1c6b43b94e55e68e02fa618f..b76d479008837b049de91c889ab7db63f9e74492 100644 (file)
@@ -26,6 +26,7 @@ import {
   // @ts-ignore
   ComponentOptionsMixin,
   MaybeRef,
+  AnchorHTMLAttributes,
 } from 'vue'
 import { isSameRouteLocationParams, isSameRouteRecord } from './location'
 import { routerKey, routeLocationKey } from './injectionSymbols'
@@ -359,6 +360,25 @@ export const RouterLinkImpl = /*#__PURE__*/ defineComponent({
  */
 export const RouterLink: _RouterLinkI = RouterLinkImpl as any
 
+/**
+ * @internal
+ */
+type _RouterLinkPropsTypedBase = AllowedComponentProps &
+  ComponentCustomProps &
+  VNodeProps &
+  RouterLinkProps
+
+/**
+ * @internal
+ */
+type RouterLinkPropsTyped<Custom extends boolean | undefined> =
+  Custom extends true
+    ? _RouterLinkPropsTypedBase & { custom: true }
+    : _RouterLinkPropsTypedBase & { 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.
@@ -366,11 +386,8 @@ export const RouterLink: _RouterLinkI = RouterLinkImpl as any
  * @internal
  */
 export interface _RouterLinkI {
-  new (): {
-    $props: AllowedComponentProps &
-      ComponentCustomProps &
-      VNodeProps &
-      RouterLinkProps
+  new <Custom extends boolean | undefined = boolean | undefined>(): {
+    $props: RouterLinkPropsTyped<Custom>
 
     $slots: {
       default?: ({
index 07c2705204d8cbe2796198c9eba15a808d6bb2ea..ac96ec0826ce53a4500f3e5e6e687181efea5e03 100644 (file)
@@ -27,6 +27,17 @@ describe('Components', () => {
     expectTypeOf<JSX.Element>(<RouterLink class="link" to="/foo" />)
     expectTypeOf<JSX.Element>(<RouterLink to={{ path: '/foo' }} />)
     expectTypeOf<JSX.Element>(<RouterLink to={{ path: '/foo' }} custom />)
+    // event handlers and anchor attrs are allowed when not custom
+    expectTypeOf<JSX.Element>(
+      <RouterLink to="/" onFocus={() => {}} onClick={() => {}} />
+    )
+    expectTypeOf<JSX.Element>(
+      <RouterLink to="/" target="_blank" rel="noopener" />
+    )
+    // @ts-expect-error: href is intentionally omitted
+    expectError(<RouterLink to="/" href="/bar" />)
+    // @ts-expect-error: onFocus should not be allowed with custom
+    expectError(<RouterLink to="/" custom onFocus={() => {}} />)
 
     // RouterView
     expectTypeOf<JSX.Element>(<RouterView class="view" />)