Skip to content

Vue instance type extending in Vue 2 project does not work #741

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rchl opened this issue Nov 28, 2021 · 8 comments
Closed

Vue instance type extending in Vue 2 project does not work #741

rchl opened this issue Nov 28, 2021 · 8 comments
Labels
question Further information is requested

Comments

@rchl
Copy link
Collaborator

rchl commented Nov 28, 2021

The types declared in the types array in tsconfig.json don't extend the Vue instance as they supposed to.

Here is a simple Vue 2 project with enabled Volar support: https://github.com/rchl/volar-vue2-test

The type of the context argument in pages/index.vue should be a Context and not any.

Screenshot 2021-11-28 at 12 37 50

It works with Vetur.

@sethidden
Copy link
Contributor

sethidden commented Nov 30, 2021

I guess this is a similar issue to nuxt/typescript#83 (comment), where @nuxt/types adds the types correctly to the Vue 2 component types (here) but that Vue 2 component type is not being used. I assume Volar even in a Vue 2 project such as yours needs to use the Vue 3-ish (hence dependency on @vue/runtime-dom) interface which @nuxt/types does not inject to

I also found https://stackoverflow.com/questions/64093409/nuxt-asyncdata-error-binding-element-axios-implicitly-has-an-any-type/64097424 but that's probably not what you want :P

@rchl
Copy link
Collaborator Author

rchl commented Nov 30, 2021

Sounds plausible. But whatever the outcome, it would be good to document the situation because as it is now, it's not really practical to use Volar for Vue 2 projects.

I wonder if this is something that can and will be addressed or not really. In the latter case, there is Vetur still, and Volar should probably not bother with Vue 2.

@johnsoncodehk
Copy link
Member

johnsoncodehk commented Nov 30, 2021

This is by design. vetur internally wraps the options in Vue.extends, but I think predictability is more important than out-of-the-box. Your code should be same behavior in <script> and *.ts, so volar avoids to hacking <script> block.

You can change it very easily to get the behavior of vetur.

+ import Vue from 'vue';

- export default {
+ export default Vue.extend({
  async asyncData(context) {
    context.error({message: 'err'})
  }
- }
+ })

@johnsoncodehk johnsoncodehk added the question Further information is requested label Nov 30, 2021
@rchl
Copy link
Collaborator Author

rchl commented Nov 30, 2021

What sort of serious project that relies on type checking would not want that? When using any external Vue plugin or just Nuxt, which itself extends Vue a lot, it's basically required or otherwise the user will see type errors everywhere.

If you insist on keeping this behavior for some reason, then it would be nice to at least document this behavior in the appropriate section in the documentation.

Also, the documentation states:

Template type-checking do not support with Vue.extend, you can use composition-api, vue-class-component, or export default { ... } instead of export default Vue.extend.

So does that mean that your suggestion will also make type checking in the template cease to work?

@johnsoncodehk
Copy link
Member

What sort of serious project that relies on type checking would not want that? When using any external Vue plugin or just Nuxt, which itself extends Vue a lot, it's basically required or otherwise the user will see type errors everywhere.

I would like to mention again that the reason is predictability. When a developer with JS/TS experience just starts to develop a vue project, he should be able to predict the IDE behavior of the code in the <script> without having to learn what the behavior of the vue IDE Plugin is different from vanilla JS/TS.

Especially for serious projects, predictability and consistency to vanilla JS/TS is crucial.

So does that mean that your suggestion will also make type checking in the template cease to work?\

Yes, see #647.

@rchl
Copy link
Collaborator Author

rchl commented Nov 30, 2021

I'm not sure I fully agree with that argument.

Most users of Vue are not familiar enough with how Vue instances are typed internally to be confused by this auto-typing happening behind their back.

Let's say the user is very familiar with typescript and types but not so much with how Vue instances are typed behind the scenes. Wouldn't the user be already very confused by the fact that the props, data, computed and methods (among others) are flattened into the same namespace rather than being accessible through props.foo, data.bar etc.? That's magic enough to confuse the user IMO. A little more magic with the exported instance being typed properly would IMO be a minor nuance.

But in any case... I'm asking for at least clarification for this in the documentation since I would imagine this to be a common problem for people who might try Volar on a Vue 2 project. If you are open to that then I might contribute something like that.

@johnsoncodehk
Copy link
Member

If you are open to that then I might contribute something like that.

Of course PR is welcome. :)

@rchl
Copy link
Collaborator Author

rchl commented Nov 30, 2021

As for #647 and the more complicated case from #66 (comment) those appear working properly to me with Vue.extend. Or at least as well as in Vetur.

As for your comment in #66 (comment), is that really related to the issue at hand? Because I guess that doesn't work regardless if using Vue.extend or not?

I'm asking that question to be able to make better informed PR.

johnsoncodehk pushed a commit that referenced this issue Mar 6, 2022
* fix(docs): extend vue 2 info regarding types

Related #741

* update instructions as suggested
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants