From: Zcating Date: Fri, 4 Dec 2020 21:32:26 +0000 (+0800) Subject: types(watch): better typing when watching multiple sources (#2425) X-Git-Tag: v3.0.5~37 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d2d27b2e6666d9f4325b8497134bb36267769408;p=thirdparty%2Fvuejs%2Fcore.git types(watch): better typing when watching multiple sources (#2425) --- diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index af54568823..f0ff31fcfd 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -78,15 +78,26 @@ export function watchEffect( // initial value for watchers to trigger on undefined initial values const INITIAL_WATCHER_VALUE = {} +type MultiWatchSources = (WatchSource | object)[] + // overload #1: array of multiple sources + cb -// Readonly constraint helps the callback to correctly infer value types based -// on position in the source array. Otherwise the values will get a union type -// of all possible value types. export function watch< - T extends Readonly | object>>, + T extends MultiWatchSources, Immediate extends Readonly = false >( - sources: T, + sources: [...T], + cb: WatchCallback, MapSources>, + options?: WatchOptions +): WatchStopHandle + +// overload #2 for multiple sources w/ `as const` +// watch([foo, bar] as const, () => {}) +// somehow [...T] breaks when the type is readonly +export function watch< + T extends Readonly, + Immediate extends Readonly = false +>( + source: T, cb: WatchCallback, MapSources>, options?: WatchOptions ): WatchStopHandle diff --git a/test-dts/watch.test-d.ts b/test-dts/watch.test-d.ts index 84c6e542b5..52d26c93c4 100644 --- a/test-dts/watch.test-d.ts +++ b/test-dts/watch.test-d.ts @@ -11,8 +11,8 @@ watch(source, (value, oldValue) => { }) watch([source, source2, source3], (values, oldValues) => { - expectType<(string | number)[]>(values) - expectType<(string | number)[]>(oldValues) + expectType<[string, string, number]>(values) + expectType<[string, string, number]>(oldValues) }) // const array @@ -34,8 +34,10 @@ watch( watch( [source, source2, source3], (values, oldValues) => { - expectType<(string | number)[]>(values) - expectType<(string | number | undefined)[]>(oldValues) + expectType<[string, string, number]>(values) + expectType<[string | undefined, string | undefined, number | undefined]>( + oldValues + ) }, { immediate: true } ) @@ -61,3 +63,15 @@ watch(nestedRefSource, (v, ov) => { expectType<{ foo: number }>(v) expectType<{ foo: number }>(ov) }) + +const someRef = ref({ test: 'test' }) +const otherRef = ref({ a: 'b' }) +watch([someRef, otherRef], values => { + const value1 = values[0] + // no type error + console.log(value1.test) + + const value2 = values[1] + // no type error + console.log(value2.a) +})