DarkLite1
DarkLite1

Reputation: 14725

Vue watch TypeScript error TS2769: No overload matches this call

Consider the following code:

export default defineComponent({
  setup() {
    const miniState = ref(true)

    const setMiniState = (state: boolean, screenWidth: number) => {
      if (screenWidth > 1023) {
        miniState.value = false
      } else if (state !== void 0) {
        miniState.value = state === true
      }
      else {
        miniState.value = true
      }
    }

    watch('$q.screen.width', (width) => setMiniState(true, width))

    return { miniState, setMiniState }
  }
})

TypeScript throws this error:

TS2769: No overload matches this call.
Overload 1 of 3, '(source: SimpleEffect, options?: Pick, "deep" | "flush"> | undefined): StopHandle', gave the following error. Argument of type '"$q.screen.width"' is not assignable to parameter of type 'SimpleEffect'.

Overload 2 of 3, '(source: WatcherSource, cb: WatcherCallBack, options? Partial | undefined): StopHandle', gave the following error. Argument of type '"$q.screen.width"' is not assignable to parameter of type 'WatcherSource'.

Overload 3 of 3, '(sources: WatcherSource[], cb: (newValues: unknown[], oldValues: unknown[], onCleanup: CleanupRegistrator) => any, options?: Partial | undefined): StopHandle', gave the following error. Argument of type '"$q.screen.width"' is not assignable to parameter of type 'WatcherSource[]'.

This is for the following line of code:

watch('$q.screen.width', (width) => setMiniState(true, width))

As it stands I'm handing over a string to the watch function instead of WatcherSource<any>. I tried the following but they all fail:

watch('$q.screen.width' as WatcherSource, (width) => setMiniState(true, width)) // fails

watch(('$q.screen.width' as WatcherSource ), (width) => setMiniState(true, width)) // fails

What is the correct way to solve this?

Upvotes: 1

Views: 10857

Answers (2)

GoodLuc
GoodLuc

Reputation: 129

I've had this problem with Quasar and it turned out to be that VS Code somehow auto-imported the wrong "watch" object like so:

import { watch } from 'fs';

instead of

import { watch } from 'vue';

And that's why it was expecting the wrong type paramenters.

Just a heads up in case anyone else has the same issue.

Cheers

Upvotes: 12

J&#243;zef Podlecki
J&#243;zef Podlecki

Reputation: 11283

Here's the definition of watch and WatcherSource

function watch<T>(
  source: WatcherSource<T>,
  callback: (
    value: T,
    oldValue: T,
    onInvalidate: InvalidateCbRegistrator
  ) => void,
  options?: WatchOptions
): StopHandle

type WatcherSource<T> = Ref<T> | (() => T)

According to that you should either pass ref or callback.

watch(() => $q.screen.width, (width) => setMiniState(true, width))

Upvotes: 5

Related Questions