Open cnzgray opened 2 months ago
Thank you for reporting this issue.
FYI: this issue has existed prior to the changes merged in v3.4.35. However, I agree that it requires further investigation and testing.
Sorry, you’re right; this issue has existed in previous versions.
I just checked the type definition of UnwrapRef and found it strange. Why is it defined as UnwrapRefSimple
instead of the following UnwrapRef
?
T extends ReadonlyArray<any>
? {
[K in keyof T]: UnwrapRef<T[K]>;
}
Refer to the playground below.
I hope this helps you.
It seems that types are correct here since this is actually intended behavior: https://github.com/vuejs/core/blob/b1abac06cdb198bd72f8e614b1f68b92e1c78339/packages/reactivity/src/baseHandlers.ts#L152-L155
You can find reasoning for this behavior here: https://github.com/vuejs/core/commit/775a7c2b414ca44d4684badb29e8e80ff6b5d3dd
This is reflected in the documentation as well: https://vuejs.org/api/reactivity-core.html#reactive
It should also be noted that there is no ref unwrapping performed when the ref is accessed as an element of a reactive array or a native collection type like Map.
I apologize for revisiting the responsive implementation code. The current type definition is reasonable. The issue lies with TypeScript arrays; you can check this playground.
interface UnrelatedValue<T, S=T> {
get value(): T;
set value(v: S);
}
const a = [] as Array<UnrelatedValue<number, string|number>>;
a.push({ value: 1 });
a.push({ value: "1" }); // ts(2322)
a[0].value = 2;
a[0].value = "2";
I've discovered a new test case
In the environment of ts 5.5.4 + vue 3.4.34
, the following code can correctly infer the type.
Playground for 3.4.34
import { ref } from "vue";
const g = { g: 0, h: "h" }
const e = {
f: ref(g),
};
const c = {
d: ref([e]),
};
const a = ref({
b: ref([c]),
});
a.value.b[0].d[0].f = g; // f type is { g: number; h: string; }
However, in the environment of ts 5.5.4 + vue 3.4.35
, there is an error in type inference.
Playground for 3.4.35
a.value.b[0].d[0].f = g; // error 7053
I think the problem is related to the behavior of "Unrelated Types for Getters and Setters" under array type inference, so if TypeScript does not correctly address the issue with arrays, it might not be suitable to incorporate "Unrelated Types for Getters and Setters" into Vue.
Thank you for the test case; it's an interesting example. As far as I can tell, this was caused by the result of the ref
function being declared as Ref<UnwrapRef<T>, UnwrapRef<T> | T>
. After the fixes in https://github.com/vuejs/core/pull/11536, the types in this example work correctly.
Vue version
3.4.35
Link to minimal reproduction
https://play.vuejs.org/#eNp9kcFuwjAMhl/FyoVVQi2U7VI6pG3isE0a0+BG0FSKYWVtEiVph4T67nNSDThMXKLY32/rt31kD0qFTY0sYanJdaEsGLS1mnBRVEpqC0fQuIUWtlpW0CNpjwsucimMhQzuHb05cgGwTvx/EPRdlHfR0j3DoO+DOFgFXLTB2HXIwiYrawzX1GM4hiiC2es5my8HKwKxB4t5AvEojl1ZGnU2ySAFFitVZhYpAkg3RTNJI/c63QVjfWYNWd4Wu3BvpKBpvWXOclmpokQ9U7agkThLwBPHsrKUPy8+Z3WNfixf84X59z/5vTm4HGfvGg3qBjk7MZvpHdoOT+dveKD/CVZyU5ekvgI/0Miydh472WMtNmT7QufdPvubFWK3MNODRWH+hnJGnbL1es7ojk9XRj/bHYW3vo7uRlv8bFC7nrRAAuHojrW/e2S5SQ==
Steps to reproduce
PR #11442 is not just a TS>5.1 issue; it also requires additional testing for nested Ref arrays.
What is expected?
What is actually happening?
System Info
Any additional comments?
https://vuejs.org/api/reactivity-core.html#ref