Subscribe on changes!

type of reactive collection values is not unrefed

avatar
May 19th 2022

Link to minimal reproduction

https://codesandbox.io/s/gallant-glade-l6n6g5?file=/src/index.ts

Steps to reproduce

Comment line 5 and uncomment line 6 and there will be a typescript error indicating typeof m is Map<string, { a: Ref<number> }>, same for line 7 and line 8, line 14 and line 15, line 16 and line 17.

From the output, we know that values got from m.get is actually { a: number }, which is inconsistent with the typing.

What is expected?

typeof reactive(new Set<{ a: Ref<number> }()) is Set<{ a: Ref<number> }> so we can use .a.value or is Set<{ a: number }> so we can use .a on set items.

What is actually happening?

typeof reactive(new Set<{ a: Ref<number> }>()) is inferred as Set<{ a: Ref<number> }> but is actually Set<{ a: number }>. Same for Map.

System Info

No response

Any additional comments?

No response

avatar
May 19th 2022

Use ref, when get the value, if the target is Array and key is Integer will return res other cases will return res.value.

image

avatar
May 19th 2022

@liulinboyi objects in reactive Maps will be reactive as well, and thus refs inside of them will be unwrapped, but the type doesn't reflect that - that's the problem.

avatar
May 19th 2022

@liulinboyi objects in reactive Maps will be reactive as well, and thus refs inside of them will be unwrapped, but the type doesn't reflect that - that's the problem.

You are right, the type doesn't reflect that😉.

avatar
May 19th 2022

I'll remove the bug label for now as I have a feeling this was an intentional choice, yet I think we can look deeper into it to see how this experience can be improved.

For now, one would make sure that reactive()/ref() receive Maps whose generic types are already unwrapped:

// bad
const map = reactive(new Map<string, { foo: Ref<string>}>())
map.set('foo', { foo: ref('bar') })

// good
const map = reactive(new Map<string, { foo: string }>())
map.set('foo', reactive({ foo: ref('bar') }))