vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.48k stars 8.3k forks source link

`UnwrapNestedRefs` won't reflect getter and setter properly #3797

Open yaquawa opened 3 years ago

yaquawa commented 3 years ago

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.

hyf0 commented 3 years ago

duplicate of #3478

HcySunYang commented 3 years ago

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

hyf0 commented 3 years ago

@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)
yaquawa commented 3 years ago

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

hyf0 commented 3 years ago

@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