Computed properties cannot with different types in getter/setter in TypeScript
Vue version
3.2.45
Link to minimal reproduction
https://sfc.vuejs.org/#eNqVUk1LxEAM/StxLt2FbYseS7coIijoRQQvA9Jds7XS+WAmVaT2v5uZ6bpePbWZl7y8vGQSV9YWHyOKStR+73pL4JFGC0Oru60U5KVopO6VNY5gAoeHDeyNsiPhK8xwcEZBxgSZ1FLvjfYEL8p3sA2ptR7VDl2zOl8fwYQdGVaT1AAdUgWrNWybWFt8tMOIm4CwFkZiXEEig2/w5HrdxfxYL+lUxuTxy3JolnrmxmUJ9GXRHELzCp5dT+1uwOtFw+NJZ5jhL1N2wWMt5ZClthn0HrQhaL3vOx2YgMySkni4qC6Tm5GyJlR2aAk5AqjfzptpikbMc11yFF97zWqgiq3ZeIalgMv4yiGraRbvVlhQ69gzVgC3Tw/3dyHnZkCFmtZJe1wak57leRr6vxNAnjNDXf4qFxuRjiBXrS3evdF8Msn9BeBLqdI+whufRIileCOyvipLf9iHQ3v3hXFdyX+FGzX1Cgv0Kt858+nRMbEUgSKsTsw/487lnQ==
Steps to reproduce
Define a computed property, getter type is number, setter type is number | string.
The computed property type is WritableComputedRef<number>.
And cannot set a string to its value.
What is expected?
Can set both a string and a number to the value of computed property.
What is actually happening?
type 'string' is not assignable to type 'number'
System Info
System:
OS: Windows 10 10.0.22621
CPU: (8) x64 Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz
Memory: 1.66 GB / 11.80 GB
Binaries:
Node: 19.0.1 - D:\Program Files\nodejs\node.EXE
Yarn: 1.22.17 - ~\AppData\Roaming\npm\yarn.CMD
npm: 8.19.2 - D:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Spartan (44.22621.819.0), Chromium (107.0.1418.62)
Internet Explorer: 11.0.22621.1
Any additional comments?
TypeScript is support different types for getter and setter now.
A suggested solution is to define the type of Writable Computed Ref as WritableComputedRef<number, number | string>.
It will work if you set const _msg = ref<number | string>(1).
@otomad You need to do computed<string | number>({...)
This is fully documented: https://vuejs.org/guide/typescript/composition-api.html#typing-computed
You need to do
computed<string | number>({...)
@ferferga If you do computed<string | number>({...) then computed's value will have type string | number and not number, so it's not a solution
@jacekkarczmarczyk What's the use case for this though? I think allowing this is error-prone.
Computed are derived state, and as such, the getter should have some relation with the setter.
With pure (non-reactive) variables, TypeScript doesn't allow to define a type for "getting" and another for "setting". Neither in classes. It's a bad design pattern. Why should this be in core?
Computed should not be treated like functions, but as variables (more precisely, getters)
I understand that the original poster's issue is that the original get value is just a number, so TypeScript just infers it as a number and needs additional info (in this case a type annotation) to know it can be a string too.
I've only pointed out that your "solution" is not a solution for the problem. Whether the feature can be implemented or not or what are the use cases is a different thing
Anyway, most probably it can't be implemented because of ts limitations, here's a long discussion on this topic: https://github.com/microsoft/TypeScript/issues/2521
I understand that the original poster's issue is that the original get value is just a number, so TypeScript just infers it as a number and needs additional info (in this case a type annotation) to know it can be a string too.
@jacekkarczmarczyk This is why I said it's a solution in my first message, since I believed it's a misconception (though probably I shouldn't have done that in the first place 😊).
The issue has been resolved by PR #11472