Type of ref for Map with generic in values is abnormal.
Vue version
3.3.10
Link to minimal reproduction
Steps to reproduce
- Create ref with Map that use generic
const reactiveMap = ref(new Map<number, T>());
- Try to assign value from crated map in other place that expect this generic:
const test: T = reactiveMap.value.get(1)
You can check typescript error on line 14 in App.vue file in reproduction link.
What is expected?
Code works without any typescript errors.
What is actually happening?
Got error:
Argument of type 'UnwrapRefSimple<T>[]' is not assignable to parameter of type 'T[]'.
Type 'UnwrapRefSimple<T>' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'UnwrapRefSimple<T>'
System Info
No response
Any additional comments?
This issue happens on 3.3.10 versions and works well on 3.3.9 I may assume that issue related to this changes: https://github.com/vuejs/core/pull/8960/files#diff-81475b10580b705fb8421b8c430ac63220938646c0e09141be79c85b0ea392ffR499 that was included in lates release.
Values of object types are recursively unwrapped. Due to TypeScriptinability to recognize whether the values in your generic type include the Ref type, it recursively unwraps the values of the object. As a result, an UnwrapRefSimple<T>
type is obtained. You can try handling this issue as follows:
const reactiveMap: Ref<Map<number, T>> = ref(new Map());
const arr: T[] = []
arr.push(reactiveMap.value.get(1)) // T
Thanks for the answer.
Yeah, i know that i can workaround this issue by using typecast.
The your version or like this:
const reactiveMap = ref(new Map()) as Ref<Map<number, T>>;
But my point that previously it was worked correct and doesn't required any additional actions in the code. And latest changes bring this side effect so it looks like regression.
This is why i decided to report this issue.
@sinkersan the current type is correct, @Alfred-Skyblue is correct on the explanation.
the same issue is/was present since a long time ago:
function test<T>(): Ref<T> {
const r = ref<T>(null)
return r;
}
The solution is, if you're sure T
is not a ref
you need to cast it
const r = ref<T>(null) as Ref<T>
Just bear in mind that the type might not be exactly the same, because of the unwrapping.
The reason before was working was because of the type issue where collections were being ignored, but it was fixed recently and not a regression.