-
Notifications
You must be signed in to change notification settings - Fork 344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(type): align watch types with vue3 #927
Conversation
It does not seem to be a complete fix, ideally the |
Sorry but I can't get your point? The usage of Without you can try // const array
const arr = [source, source2, source3] as const
watch(arr, (values, oldValues) => {
expectType<string>(values[0])
expectType<string>(values[1])
expectType<number>(values[2])
expectType<string>(oldValues[0])
expectType<string>(oldValues[1])
expectType<number>(oldValues[2])
}) without |
The current version (with 8fb7343) allows you to do watch([ref1, ref2], ([r1, r2]) => ...) and infers the type of watch([ref1, ref2] as const, ([r1, r2]) => ...) |
I get it. Now I find another problem in vue3 const testRef = ref(4);
const testRef2 = ref(4);
const testRef3 = ref(4);
const arr1 = [testRef2, testRef3];
watch(arr1, ([foo, bar, ...rest]) => {
console.log(foo);
console.log(rest);
});
const addMember = () => {
arr1.push(testRef);
};
const newMemberChange = () => {
testRef.value++;
};
const originMemberChange = () => {
testRef2.value++;
};
return { addMember, newMemberChange, oranginMemberChange } Run |
You're talking about different example that in the issue. Your example is const arr = [whatever];
watch(arr, ([...]) => { and the example in the issue is watch([whatever], ([...]) => { |
It's a type problem, even if you const an array in this way, yes you can't change the number of it's member, but it is still be treated as Array by typescript defaultly , not a tuple nor a Readonly<[...]>. Only when you giving a tunple type to array, it becomes to a tunple, in other case typescript don't know it is a tuple. An array which will never be changed, but it's type is still Array, not a tuple |
So you must use |
I'm saying type of watch function in current version is wrong. |
Typescript's type inference never give us a tunple type unless we give an array tuple type at beginning. That's my opinion. Sorry for poor english. Of course, if typescript can make come changes on the inference of tuple in future, that is the best result. |
I see your point although I don't agree with it, but the main thing is the you titled your PR "align watch types with vue3" - which suggests that watch types should be aligned with vue3 and vue3 allows both So in my opinion if you think that vue3 is wrong you can open an issue and PR there, but for now making vue2 and vue3 working the same way is more important |
- add another overload for spread readonly array, change their sequence. - merge MapSources and OldMapSources
That's right, add another overload for watch, add more test cases ,do some change to make it works for all test cases. |
Awesome, thanks! |
这个问题不知道在 type A = [string,number]
const a: A = ['1',1] as const // 我们肯定不会这么写 但我不确信 |
ts类型不会影响代码逻辑, 到了js都是array const source2 = ref(2);
const source3 = ref(1);
const array = [source2, source3];
watch(
array,
([r2, r3, ...rest]) => {
console.log(rest);
},
{
onTrack(r) {
console.log('onTrack', r);
},
},
);
const pushV = () => {
array.push(ref(0));
};
const changeNew = () => {
array[array.length-1].value++
};
const changeOld = () => {
array[array.length-2].value++;
}; 想了想产生这个现象的原因是传给watch的deps是在依赖项触发onTrigger的时候重新收集,而对此处的watchsource数组操作并不会触发依赖的重新收集,如果要在数组操作时立即更新依赖,可能需要在外面加一层proxy,来重写数组操作,添加更新依赖的代码 |
ts类型不会影响代码逻辑, 到了js都是array 此处的例子不太恰当,我整了一个控制变量更精确的 const source2 = ref(2);
const source3 = ref(1);
const array = [source2, source3];
watch(
array,
([r2, r3, ...rest]) => {
console.log(rest);
},
{
onTrack(r) {
console.log('onTrack', r);
},
},
);
const pushV = () => {
array.push(ref(0));
};
const changeNew = () => {
array[array.length-1].value++
};
const changeOld = () => {
array[array.length-2].value++;
}; 想了想产生这个现象的原因是传给watch的deps是在依赖项触发onTrigger的时候重新收集,而对此处的watchsource数组操作并不会触发依赖的重新收集,如果要在数组操作时立即更新依赖,可能需要在传进watch的数组外面加一层proxy,来重写数组操作,添加更新依赖的代码 |
我懂这个意思,但这个和我说的不冲突,比如 Ts function fn(p: number){}
fn(1) // work
fn('2') // err Js import fn form '';
fn(1) // work
fn('2') // work ts 会限制参数类型,但在 js 世界传其他类型也可以,此处希望为一个 这上面是我个人想法,但我觉得这样可能比较合理一点。 |
按照现在的类型推断是无法推断出上面代码的 |
resolve #924