expect(dummy).toMatchObject([[2, true], [1, false]])
})
+ it('watching multiple sources: reactive object (with automatic deep: true)', async () => {
+ const src = reactive({ count: 0 })
+ let dummy
+ watch([src], ([state]) => {
+ dummy = state
+ // assert types
+ state.count === 1
+ })
+ src.count++
+ await nextTick()
+ expect(dummy).toMatchObject({ count: 1 })
+ })
+
it('warn invalid watch source', () => {
// @ts-ignore
watch(1, () => {})
expect(`Invalid watch source`).toHaveBeenWarned()
})
+ it('warn invalid watch source: multiple sources', () => {
+ watch([1], () => {})
+ expect(`Invalid watch source`).toHaveBeenWarned()
+ })
+
it('stopping the watcher (effect)', async () => {
const state = reactive({ count: 0 })
let dummy
) => any
type MapSources<T> = {
- [K in keyof T]: T[K] extends WatchSource<infer V> ? V : never
+ [K in keyof T]: T[K] extends WatchSource<infer V>
+ ? V
+ : T[K] extends object ? T[K] : never
}
type MapOldSources<T, Immediate> = {
[K in keyof T]: T[K] extends WatchSource<infer V>
? Immediate extends true ? (V | undefined) : V
- : never
+ : T[K] extends object
+ ? Immediate extends true ? (T[K] | undefined) : T[K]
+ : never
}
type InvalidateCbRegistrator = (cb: () => void) => void
// 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<WatchSource<unknown>[]>,
+ T extends Readonly<Array<WatchSource<unknown> | object>>,
Immediate extends Readonly<boolean> = false
>(
sources: T,
}
}
+ const warnInvalidSource = (s: unknown) => {
+ warn(
+ `Invalid watch source: `,
+ s,
+ `A watch source can only be a getter/effect function, a ref, ` +
+ `a reactive object, or an array of these types.`
+ )
+ }
+
const instance = currentInstance
let getter: () => any
if (isArray(source)) {
getter = () =>
- source.map(
- s =>
- isRef(s)
- ? s.value
- : callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER)
- )
+ source.map(s => {
+ if (isRef(s)) {
+ return s.value
+ } else if (isReactive(s)) {
+ return traverse(s)
+ } else if (isFunction(s)) {
+ return callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER)
+ } else {
+ __DEV__ && warnInvalidSource(s)
+ }
+ })
} else if (isRef(source)) {
getter = () => source.value
} else if (isReactive(source)) {
}
} else {
getter = NOOP
- __DEV__ &&
- warn(
- `Invalid watch source: `,
- source,
- `A watch source can only be a getter/effect function, a ref, ` +
- `a reactive object, or an array of these types.`
- )
+ __DEV__ && warnInvalidSource(source)
}
if (cb && deep) {