strictTemplates + defineModel event listener type errors
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
@clickor@changeon a component that usesdefineModeland enablestrictTemplates - 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
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.
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
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.
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)
Maybe it's possible to add an option to vue language options for globally allowed event listeners, kind of like htmlAttributes/dataAttributes settings?
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.
See: https://github.com/vuejs/language-tools/wiki/Vue-Compiler-Options#stricttemplates.