language-tools icon indicating copy to clipboard operation
language-tools copied to clipboard

strictTemplates + defineModel event listener type errors

Open Doeke opened this issue 1 year ago • 6 comments

Vue - Official extension or vue-tsc version

2.0.21

VSCode version

1.92.2

Vue version

3.4.29

TypeScript version

5.4.0

System Info

System:
    OS: Linux 6.8 Ubuntu 24.04 LTS 24.04 LTS (Noble Numbat)
    CPU: (16) x64 AMD Ryzen 7 7840U w/ Radeon  780M Graphics
    Memory: 13.28 GB / 30.66 GB
    Container: Yes
    Shell: 5.2.21 - /bin/bash
  Binaries:
    Node: 20.15.1 - ~/.nvm/versions/node/v20.15.1/bin/node
    npm: 10.8.2 - ~/.nvm/versions/node/v20.15.1/bin/npm
  Browsers:
    Chrome: 127.0.6533.119

Steps to reproduce

  • Add an event listener like @click or @change on a component that uses defineModel and enable strictTemplates
  • Run type check

What is expected?

No errors, @click is a valid native event listener on components

What is actually happening?

Error (Object literal may only specify known properties...)

Link to minimal reproduction

https://github.com/Doeke/bug-stricttemplates

Any additional comments?

Was asked to make a separate issue for this

https://github.com/vuejs/language-tools/issues/4699#issuecomment-2293417756

Doeke avatar Aug 16 '24 13:08 Doeke

Oh I'm sorry, I thought you were referring to an error when adding defineModel, so I tried to remove it and found that the error disappeared, which led me to discover another issue...

When there are no events on a component, its $emit will be inferred as any event function.

As you said, this is the same issue with fallthrough attributes. Regardless of whether there is a defineModel, it should report an error.

KazariEX avatar Aug 16 '24 13:08 KazariEX

Should it report an error? My understanding is that <MyComponent @click="onClick" /> is the correct way to add a native click event listener now that .native modifier has been removed

Doeke avatar Aug 16 '24 14:08 Doeke

IMO in strictTemplates, just as unknown props should report errors, the listening for events is similar to assigning values to the 'onXxx' prop, and it should also apply the rules of the former.

KazariEX avatar Aug 16 '24 14:08 KazariEX

My understanding is that <MyComponent @click="onClick" /> is the correct way to add a native click event listener now that .native modifier has been removed. Though I do also see the argument for not allowing this with strictTemplates and only allowing events that are defined with defineEmits. The main issue is that it is currently not consistent (only some cases it causes error)

Doeke avatar Aug 16 '24 14:08 Doeke

Maybe it's possible to add an option to vue language options for globally allowed event listeners, kind of like htmlAttributes/dataAttributes settings?

Doeke avatar Aug 16 '24 14:08 Doeke

What I'd fixed is exactly the inconsistency you mentioned.

The reason of <MyComponent @click="onClick" /> is the correct way to add a native click event listener, is because it passes click events to the root element of the component as a "fallthrough attribute", rather than the component itself containing the attribute; So when strictTemplates is enabled, it should report an error. This does not mean that this way of adding events is incorrect.

And what #4103 want to solve includes this issue.

KazariEX avatar Aug 16 '24 14:08 KazariEX

See: https://github.com/vuejs/language-tools/wiki/Vue-Compiler-Options#stricttemplates.

KazariEX avatar Feb 21 '25 05:02 KazariEX