vue icon indicating copy to clipboard operation
vue copied to clipboard

Computed properties with getter/setter do not provide expected Typescript type annotation

Open EvanSanderson opened this issue 5 years ago • 7 comments

Version

2.6.10

Reproduction link

https://codesandbox.io/s/quiet-glitter-qk7fy?fontsize=14

Steps to reproduce

  1. Create a computed property in a single file component that is lang="ts" - call it myComputedProp

  2. Add a get() and set() method for that computed prop

  3. Annotate the get() method (for example get(): string)

  4. Annotate the set() method (for example set(myValue: number): void )

  5. Check the inferred types of myComputedProp - it looks like it will be string | number

What is expected?

When the get() method of a computed property is annotated with a type, the computed properties type will correspond to that annotation.

What is actually happening?

When the get() method of a computed property is annotated with a type (A), and the set() methods parameter has been annotated with a type as well (B), the computed property has a type of A | B


This may very well be a user error on our part as well, and perhaps the community or Vue team has some suggestions for how to better handle this. We provide auto generated types from an api client, so having the "or" syntax with the computed annotation in this case means we need to use a type assertion to circumvent this. Thanks a ton! Happy to provide screenshots I took as well.

EvanSanderson avatar Oct 25 '19 18:10 EvanSanderson

Pretty sure this is intentional, otherwise you wouldn't be able to assign a number to it.

this.myComputedProp = 1 // Type '1' is not assignable to type 'string'

KaelWD avatar Oct 31 '19 06:10 KaelWD

I don't think it's possible because TypeScript forbid having different types between get and set.

image

ktsn avatar Oct 31 '19 06:10 ktsn

If the types could be different then this.myComputedProp = this.myComputedProp would be an error.

KaelWD avatar Oct 31 '19 10:10 KaelWD

@ktsn Thank you! :pray: I didn't realise I was missing type annotations on my setter, I was getting like 50 errors all over the place just because of that missing annotation!

WhyNotHugo avatar Jul 11 '20 13:07 WhyNotHugo

I don't think it's possible because TypeScript forbid having different types between get and set.

It's updated. Now typescript allows different types for get and set.

otomad avatar Dec 04 '22 03:12 otomad

@otomad In which version of typescript is it allowed, since I am using the computed method in vue and it sends me an error that I cannot use different types

    const amount = computed({
      get(): BigNumber {
        return new BigNumber(car.modelValue)
      },
      set(new_val: string) {
        emit("update:modelValue", new_val)
      },
    })

joserick avatar Mar 05 '23 01:03 joserick

@joserick It's in native TypeScript. However, the type of setter must contain the type of getter. For example:

const obj = {
    get amount(): BigNumber {
        return new BigNumber(car.modelValue);
    },
    set amount(new_val: string | BigNumber) {
        emit("update:modelValue", new_val);
    },
};

otomad avatar Mar 05 '23 04:03 otomad