router icon indicating copy to clipboard operation
router copied to clipboard

Using event handler with `RouterLink` combined with `vueCompilerOptions` `strictTemplates` gives TS error

Open line301u opened this issue 9 months ago • 3 comments

Reproduction

https://github.com/line301u/reproduction-vuerouter-issue-routerlink-stricttemplates

Steps to reproduce the bug

The steps are already added to the reproduction: run pnpm run type-check to get the TS error

If setting up a new vue project, use these steps to reproduce: In your the tsconfig.json, add:

  "vueCompilerOptions": {
    "strictTemplates": true
  },

Use RouterLink component with any event handler - e.g.: <RouterLink to="/" @focus="console.log('focus')" />

Run typecheck with the following command: pnpm run type-check

Expected behavior

I wouldn't expect to get an error for using event handlers on the RouterLink component

Actual behavior

If you use the vueCompilerOptions strictTemplates feature, and add any event handler to the RouterLink component, it will give a TypeScript error because of the handler. The actual functionality of the handler works.

Additional information

No response

line301u avatar Mar 28 '25 12:03 line301u

I thought the RouterLink component was already accepting the allowed props but maybe not.

posva avatar Mar 28 '25 13:03 posva

I thought the RouterLink component was already accepting the allowed props but maybe not.

@posva Just tried adding AnchorHTMLAttributes to $props in RouterLink.ts: https://github.com/vuejs/router/blob/8e387338c40cd0d68fc02f8ee8fb83d6a3b834f0/packages/router/src/RouterLink.ts#L367-L372

export interface _RouterLinkI {
  new (): {
    $props: AllowedComponentProps &
      ComponentCustomProps &
      VNodeProps &
      RouterLinkProps &
      AnchorHTMLAttributes

Running it in the playground it seems to fix this specific type error but I'm not strong enough with vue internals to tell if this has side effects. What do you think?

MikeBellika avatar Mar 31 '25 13:03 MikeBellika

It should be good although they are lost if the component is passed custom prop. It's worth making the RouterLink component generic for this. It might be more complicated than it seems.

posva avatar Mar 31 '25 14:03 posva

It should be good although they are lost if the component is passed custom prop. It's worth making the RouterLink component generic for this. It might be more complicated than it seems.

I was first thinking about a simple union-based option so custom would work, but attributes really get lost and it seems we actually need a generic with two branches to keep runtime consistency. And if I see it right, we also need to omit href from AnchorHTMLAttributes so it doesn’t become allowed (we still use to via router.resolve(to), but user won’t see TS error without omitted href).

Would be glad to take this issue, since in my work project we are migrating to Vue 3 and this came up with the new router.

hodimbokom avatar Sep 06 '25 08:09 hodimbokom