Subscribe on changes!

`UnwrapNestedRefs` won't reflect getter and setter properly

avatar
May 20th 2021

Version

3.1.0-beta.3

Reproduction link

https://codesandbox.io/s/modest-banzai-3in42?file=/index.ts

Steps to reproduce

import { reactive } from "vue";

class Thing {
  get size(): number {
    return 100;
  }

  set size(value: string | number | boolean) {}
}

const thing = reactive(new Thing)

// works
thing.size = 42;

// but, these won't work where it really should
thing.size = "hello";
thing.size = true;


// for now, to workaround I have cast it back to the original type
(thing as Thing).size = "hello";

As from TypeScript 4.3, Separate Write Types on Properties is going to be possible.

But the TypeScript support of UnwrapNestedRefs won't work for this new feature currently.

avatar
May 25th 2021

duplicate of #3478

avatar
May 25th 2021

@iheyunfei Maybe not a duplicate? this one is talking about the same property with different types of setter/getter.

avatar
May 26th 2021

@HcySunYang I think that @yaquawa means Vue3 can use this feature to fix the problem in #3478.

const foo = reactive({bar: 3)}
// type error
foo.bar = ref(5)
avatar
May 26th 2021

@iheyunfei kind of similar issue, but not exactly I think.

avatar
May 26th 2021

@yaquawa Oh, I get it. #3791 may be helpful and it should work with typescript4.3 well. I'm not sure if it is recommended, but I would suggest only using plain object in reactive or ref and markRaw for non-plain-object.

The reflection won't be easy or is even impossible. I play around it and find out that typescript doesn't provide a way to get the type of setter https://www.typescriptlang.org/play?ts=4.3.0-beta#code/FAYwNghgzlAEAqALAlgOwOawN7FrdApgC6xTIBeBAFAJQBcsqArgLYBGBATtrnrJ8SadUsAIwAGcQG5eAX2C8oxUhWoA3CGCYEGUIpzSYAPo1YduJtgHsrYAhFQ1s8+aCuo9sCLAC8jAgDuCCgYwEQAngAOBLAAZr6wVBHRVvEQNADaAORklFkAukA