vue
vue copied to clipboard
Computed properties with getter/setter do not provide expected Typescript type annotation
Version
2.6.10
Reproduction link
https://codesandbox.io/s/quiet-glitter-qk7fy?fontsize=14
Steps to reproduce
-
Create a computed property in a single file component that is lang="ts" - call it myComputedProp
-
Add a get() and set() method for that computed prop
-
Annotate the get() method (for example get(): string)
-
Annotate the set() method (for example set(myValue: number): void )
-
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.
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'
I don't think it's possible because TypeScript forbid having different types between get
and set
.
If the types could be different then this.myComputedProp = this.myComputedProp
would be an error.
@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!
I don't think it's possible because TypeScript forbid having different types between
get
andset
.
It's updated. Now typescript allows different types for get
and set
.
@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 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);
},
};