language-tools: Detect unknown/undefined prop usage
This is a proposal for enhancing vue-tsc
Example:
<MyComponent
:propThatDoesNotExist="42"
/>
When running npx vue-tsc --noEmit i want it to detect that propThatDoesNotExist is not presently defined in myComponent. This could produce a warning or error.
Feature like this currently exists in TS files. When trying to edit fields that is not defined in some typescript class it will output: Property ‘xxx’ does not exist on type ‘MyClass’.
This would be very helpful for Vue developers when renaming props or performs refactoring or git rebases as looking through the code manually can be tedious.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 4
- Comments: 45 (16 by maintainers)
Commits related to this issue
- fix: type errors https://github.com/johnsoncodehk/volar/issues/1077 — committed to ouuan/codle by ouuan 2 years ago
- feat: add `experimentalSuppressUnknownPropErrors` option #1077 — committed to vuejs/language-tools by johnsoncodehk 2 years ago
- fix: remove html.d.ts https://github.com/johnsoncodehk/volar/issues/1077#issuecomment-1146584565 — committed to antfu-collective/vitesse by antfu 2 years ago
- fix: remove html.d.ts https://github.com/johnsoncodehk/volar/issues/1077#issuecomment-1146584565 — committed to antfu-collective/vitesse-lite by antfu 2 years ago
- fix: remove html.d.ts https://github.com/johnsoncodehk/volar/issues/1077#issuecomment-1146584565 — committed to Mo60/Mo60.github.io by antfu 2 years ago
In 0.36, custom / unknown attrs types behavior handle responsibility will transfer to developer.
This isn’t just about fallthrough either, as shown in https://github.com/johnsoncodehk/volar/issues/1383 this is causing errors for many completely standard HTML attributes directly on the elements. It seems unreasonable requiring people to add custom declaration files to avoid that
Until this is fixed, the proper solution is to revert this feature or hide it behind a flag and release a new version because in the current state it’s just plane broken
I agree that this type of strict linting should be opt-in, fallthrough attributes are a common use case with Vue and the default configuration of Volar should just work with the examples from the Vue docs.
Can you make this disabled by default instead?
I still don’t understand what the real point is, as this change breaks totally valid code all over the place for known attributes like all aria attributes.
I’m sure there’s good intentions here, but people (especially new users) will have no idea what is going on when their
data-
attributes are throwing errors suddenly.I got you. Yes, you are right I can confirm its is not working. Its only working for HTML Elements.
For a temporary workaround till the time there’s a no solution to this my recommendation is that you switch your Volar Extension Version to the ‘0.35.2’ and Restart the Visual Studio Code.
This change is bonkers! How do volar check where this attribute that I passed on purpose ends up? Does it just “assumes” it is the root element of the template? But even that doesn’t work properly. Vue has an attribute fallthrough on purpose and this change makes vue-tsc crash on basically every component where I use attribute fallthrough (which I use A LOT).
This feature should be opt-in and not opt-out.
How can I disable this?
Is it possible to make an option like mode=“strict” to change default behavior? I mean, props existence check looks like an edge case than something default. Because everything that not described in props are custom attributes, that’s vue default behavior
Fix by ba2835fdcf233cad92bdd39519c0d723b7dee42e.
In v0.36.1 this behavior is control by
vueCompilerOptions.experimentalSuppressUnknownJsxPropertyErrors
and default enabled, if you want report unknown props you need config:If you see how volar hacking JSX types to ignore unknown prop errors, you may want to disable it. (This shouldn’t be part of volar’s control)
https://github.com/johnsoncodehk/volar/blob/104af79387fec40ec3c9e82299f1258f1947673e/packages/vue-typescript/src/typescriptRuntime.ts#L282-L290
I can confirm that the update fixes all issues. The feature is now opt-in as described above. Thank you for the quick fix!
Okay I’ll give it a spin later.
Just to clarify:
data-
andaria-
attributes are not unknown jsx attributes/properties.So regardless of the setting, these should never throw errors, which was the original issue.
Thanks to this feature, I noticed that the Vuetify property names had been updated and was able to correct them. 😃 However, it took some work to resolve the issue. FYI:
@vue/runtime-core
and@vue/runtime-dom
todependencies
(probably because I use pnpm)..d.ts
file must be separate from the file defining the vite’sImportMetaEnv
(if any).For now, I use the following definition in
env2.d.ts
.Complex libraries such as Vuetify do not always have all properties defined (especially if they are passed through), and users will end up having to disable the feature completely. The ideal solution would be for the type definitions of Vuetify components to be updated, but this is not always done quickly. It seems difficult to use without at least a way to define additional attributes for individual components.
FWIW, the fix outlined in the comment above related to updating the
env.d.ts
file is not working in my team’s project. Unsure of the exact reasons, but one potential difference is our team is still using Vue 2 /w the composition API, so declaring types on@vue/runtime-core
(and potentially even@vue/runtime-dom
) may not be working as expected.Still trying to troubleshoot and find a more concrete reason why it’s not working for us, but figured I’d share that in case other Vue 2 users are finding the fix is not working for them too.
EDIT: Has me wondering if it would be possible to add a feature to Volar where it uses the project’s version of
vue-tsc
instead of the built-in version - that way these breaking changes can be opted into by updating your project’s dependencies.I assume the good intent. As people mentioned, standard html attributes throw errors. So I wonder why DX is being traded for being strict on unknown props?
What is the point of making it strict and then advising people to allow any attribute? Why not allowing any html attributes by default rather than expecting people to update their
env.d.ts
files?Let’s imagine
data-cy
attribute used for testing, is it treated as HTMLAttributes or AllowedComponentProps?@IceBlizz6 You should use
vueCompilerOptions.strictTemplates
, see https://github.com/johnsoncodehk/volar/blob/master/CHANGELOG.md#0384-2022711.Imo this feature would be only useful if volar could analyze which element receives the attributes in the end. And only then, it can perform a check if that attribute is valid on that element. However, this is almost impossible to analyze statically because you can change where your attrs end up as you want.
It doesn’t make sense to me to restrict passing attributes to a component because that basically takes away a lot free customizability (look at all attributes you can give to inputs for validation reasons. You don’t want that as a prop).
So i can’t even make pure component wrapper to my button without adding env.d.ts 😄 Because this component don’t have props at all
Thankyou @johnsoncodehk I can confirm adding this code to env.d.ts file has solved the unknown property problems for both HTML and Vue Component Elements. Keep up the good work. We all appreciate what you are doing on Volar!
As @TheDutchCoder said,
data-*
andaria-*
are not unknown attributes, specially on “plain” html elements. They are standard W3C recommendations. The following piece of code is valid html and it should not throw an error regardless of the setting:Not so great… like build-in vue directive, it should not throw an error, such as v-show etc… right?
You should use
AllowedComponentProps
interface, please check updated example code.exactly. it might work for html elements but attribute fallthrough for components doesn’t work at all
@lohchab I can’t make it work on components
LIke on native elements it works fine, but what about component attributes? I have VInput component which is just a wrapper around native input. SO i have to describe ALL native attributes in props to apply them?
I also think it is great to have this feature. IMO
data-*
andaria-*
can be ignored even if it is not used.This is intentional behavior as this is often used in css selectors.
I’ll explore add a option in vueCompilerOptions to change this behavior.