Unwrapping of deep ref in Map is not correct
Vue version
3.3.4
Link to minimal reproduction
Steps to reproduce
Run the play ground in link and see that nested ref inside Maps are unwrapped even that documentation and Typing says it should not.
ref: documentation: https://vuejs.org/guide/essentials/reactivity-fundamentals.html#caveat-in-arrays-and-collections
What is expected?
Ref inside Map should not be unwrapped even when inside nested object.
What is actually happening?
const map2 = reactive(new Map([['count', {foo: ref(0)}]]))
// Typescript thinks it need value but it is unwrapped
console.log(map2.get('count').foo.value) // returns undefined
System Info
No response
Any additional comments?
No response
Hello @bergmorten I checked the code and I believe this is the expected behaviour:
- when you access
map2.get('count')
the check is done onmap2
which is aMap
so it's marked asTargetType.COLLECTION
thus its content won't be unwrapped (here is an object{foo: ref(0)}
) - then when you access
.foo
the check is done onmap2.get('count')
which is now an object, it'll be marked asTargetType.COMMON
thus unwrapped (no need for.value
)
In comparison to
const map = reactive(new Map([['count', ref(0)]]))
// need .value here
console.log(map.get('count').value)
Accessing map.get('count')
won't unwrap the content, thus resulting in the ref(0)
for which you need .value
I thought the reason for not unwrapping inside map or array was a performance decision and therefor though this was an error, If this is expected behaviour then the typing is wrong (and possible documentition). The type hint says that you need foo.value (which returns undefined when executed).
I created a PR to update the typing to infer the type of the collection value (Map, Set..) and tries to recursively unwrap it, I believe that the documentation can be more clear around this detail