vuejs / vetur

Vue tooling for VS Code.
https://vuejs.github.io/vetur/
MIT License
5.75k stars 593 forks source link

Intellisense not always working in computed properties #1707

Open Soresu opened 4 years ago

Soresu commented 4 years ago

Info

Problem

Intellisense is not working when the computed property returns a reference from this, and the component has props, even its empty. I belive this is the same as #1509 , but the return part is not visible in the picture.

Reproducible Case

You can check the example repo, I've changed Counter.vue file

image

nekosaur commented 4 years ago

This might be platform specific? This is on OS X

Screenshot 2020-02-17 at 20 25 41

But on W10 I got the same result as you

alexandrmiee commented 4 years ago

I reproduce this bug on Win10, Ubuntu Vetur 0.24.0 Soleved by set @returns option to all computed props image

F0rsaken commented 4 years ago

It's connected with this https://vuejs.org/v2/guide/typescript.html#Annotating-Return-Types and issue with circular dependencies in TypeScript >= 3.4.x

Even if you don't use TS, Vetur does and not annotating return type of computed kind of breaks this context.

cerinoligutom commented 4 years ago

Getting this as well. What's odd is when the return keyword is there, it breaks: image

When not: image

F0rsaken commented 4 years ago

@cerino-ligutom when the return is used, TypeScript wants to infer the return type of the computed test that depends on this, but this depends on also computed test, but test....

And we go into recursive loop....

cerinoligutom commented 4 years ago

@cerino-ligutom when the return is used, TypeScript wants to infer the return type of the computed test that depends on this, but this depends on also computed test, but test....

And we go into recursive loop....

Then how come that's not the case in methods? Or is it just the current typedefs for Vue2?

F0rsaken commented 4 years ago

I actually don't know. I never thought about it, but it's probably because methods and computed have different way of typing

F0rsaken commented 4 years ago

ok, I found it. ComponentOptions are based on generics. And every generic is taken almost literraly, except for Computed's, that are wrapped in another generic Accessor AND mapped with index signatures and operator keyof like this:

image

and that mapping is where TypeScript fails unfortunately.

Soresu commented 4 years ago

@F0rsaken And how is it connecting to props? When I don't use props in the component, the intellisense is fine.

F0rsaken commented 4 years ago

@Soresu props are also deeply nested in generics and mapped with index signatures.

image

I'm only guessing, but you aren't not using type: ... field. This is where you declare a prop's type, therefore the type don't need to be infered.

But actually, props don't use this.... so maybe it's something different....

yoyo930021 commented 4 years ago

If vetur.useWorkspaceDependencies: true, you will use typescript@2.9.2 in vetur and not have any error. The error is happened when using typescript@^3.x.x. It's a type definition error in Vue lib. Ref: vuejs/vue#11235

dav245 commented 4 years ago

I have been fighting with similar issue last few days. My problem was slightly different. When i defined props inside of SFC, intellisense just stopped working. Using typescript@2.9.2 actually solved it. Thank you.

yoyo930021 commented 4 years ago

Duplicate of #1509

octref commented 4 years ago

Writing this once for all. The bug is that when you have computed, TypeScript cannot infer this type correctly and cannot provide correct auto-completion and type-checking. Simplest repro case:

TS upstream issue, and it seems TS wouldn't fix it: https://github.com/microsoft/TypeScript/issues/30854#issuecomment-485893681

Your solutions:

But I'm not using TS! Why should I care?

Vetur uses TypeScript to figure out the type of your Vue component and provide all kinds of language features (completion, diagnostic error), even for Vue+JS components. Of course you can turn off the diagnostic error, but in return you will not get many of the features brought to you by TypeScript.

rchl commented 4 years ago

Writing this once for all.

It's not very discoverable at the end of some random issue. As I said elsewhere, it would be good to make this prominent. Either by having a pinned issue or including in documentation.

Uninen commented 4 years ago

I created a PR for adding this in the FAQ: https://github.com/vuejs/vetur/pull/2250

OmgImAlexis commented 3 years ago

This seems related but I'm using ts so I'm not sure what todo at this point. If it's unrelated please let me know and I'll open a seperate issue.

Convert your project to use TS + Vue, and manually write computed property return types.

The last suggestion doesn't seem to help, or maybe I'm doing it wrong? I tried both ways I know of returning a type and neither seems to fix the Vetur issue yet it does show the type in intellisense.

I have v0.31.3 of Vetur, Vue v3.0.5 and Typescript v4.1.3 installed.

Screen Shot 2021-01-10 at 3 42 22 pm Screen Shot 2021-01-10 at 3 48 17 pm
dospunk commented 3 years ago

I'm having the same problem as @OmgImAlexis

Zzombiee2361 commented 3 years ago

But how do I annotate computed with setter?

computed: {
  /** @returns {array} */
  fullItems () {
    return this.items.concat(this.selected);
  },
  open: {
    get() {
      return this.value;
    },
    set(val) {
      this.$emit('input', val);
    }
  }
}

I tried adding JSDoc above open and get() but intellisense still not working. Is this unsupported?

rchl commented 3 years ago

Haven't tried but I would guess something like this:

computed: {
  /** @returns {array} */
  fullItems () {
    return this.items.concat(this.selected);
  },
  open: {
    /** @return {string} *//
    get() {
      return this.value;
    },
    /** @param {string} val *//
    set(val) {
      this.$emit('input', val);
    }
  }
}
Zzombiee2361 commented 3 years ago

Ah I see, so I have to add JSDoc to the setter as well. Thank you

hufeng commented 2 years ago

if the computed attribute contains the mapState of vuex,How to add jsdoc?