vuejs / language-tools

⚡ High-performance Vue language tooling based-on Volar.js
https://marketplace.visualstudio.com/items?itemName=Vue.volar
MIT License
5.82k stars 396 forks source link

Template types have `any` type in Vue 2 component without "computed" property #1603

Closed rchl closed 2 years ago

rchl commented 2 years ago

If a component doesn't have any computed properties then template types are all untyped (any). Adding a single computed property makes it all work.

Repro:

  1. Clone https://github.com/rchl/volar-vue2-test.git
  2. Open pages/index.vue
  3. Hover variables in the template and see that all have any type.

This is a Vue 2.6 project with following tsconfig.json options:

  "vueCompilerOptions": {
    "strictTemplates": true,
    "target": 2,
  }
ota-meshi commented 2 years ago

FYI: It works fine with Volar v0.38.6. I think it probably didn't work well with the v0.38.7 changes.

ota-meshi commented 2 years ago

Adding the following settings seems to work fine.

  "vueCompilerOptions": {
    "strictTemplates": true,
    "target": 2,
+    "experimentalImplicitWrapComponentOptionsWithDefineComponent": true
  }

But I hope it works without needing it.

rchl commented 2 years ago

Yes, it works with that but it should also work with "experimentalImplicitWrapComponentOptionsWithVue2Extend": true which is the default value and which is necessary to make Nuxt types work (in asyncData(context) {...} for example.

johnsoncodehk commented 2 years ago

This is Vue.extend types limitation, we have nothing can do here. And please note that experimentalImplicitWrapComponentOptionsWithDefineComponent and experimentalImplicitWrapComponentOptionsWithVue2Extend is removed in v0.40.7 and replaced by experimentalComponentOptionsWrapper.

rchl commented 2 years ago

I haven't looked at the new version yet but I would like to know one thing... Is Volar aiming to support Vue 2 (including Vue 2.6) to the level of support that Vetur provides? I had impression that there is progress in that direction but it has always only worked partially so far.

Some clarity on that topic would be nice because I might be wasting my time by periodically checking Volar for Vue 2.6 support and occasionally reporting related bugs or improving documentation. If it's clearly not the goal then I can just forget about it and stick to Vetur.

In this case Vetur is arguably working better. Not sure how it does that, maybe with hacks, but it's usable at least.

johnsoncodehk commented 2 years ago

@rchl I think Vetur does some extra work to populate types other than Vue.extend, but I don't know what it actually do, appreciate if @yoyo930021 can answer.

Volar aims to provide the Vue.extend type as-is for Vue 2, so there are no plans to implement the extra work done by Vetur. Instead I think the Vue.extend type could be improve from Vue 2 library instead of being hacked into it by Volar.

In v0.40.7 vueCompilerOptions.target got respected for it. For target < 2.6, component options default wrap by Vue.extend just like Vetur does but without Vetur's hacks. And @vue/runtime-dom is optional but not a requirement any more. (But just loss some template type-checking if don't have @vue/runtime-dom) For target >= 2.7, component options default wrap by defineComponent and it should be better than Vetur in all case.

I still can't get around to writing the docs, if it goes well I'll do it this month..

rchl commented 2 years ago

OK, then it seems like Volar should be good to use with Vue 2.7>= while for Vue 2.6 people should stick to Vetur.

yoyo930021 commented 2 years ago

In my know, Vetur doesn't wrap any other function without Vue.extend. But I can study it when I have time.

mryellow commented 1 year ago

Thanks for the heads-up. Switching back to Vetur.