多个 Vue 3 观察者和 Typescript ...如何使用?

Multiple Vue 3 watchers & Typescript ... how to use?

N.B。我正在使用 @vueuse/core 库来获取以下示例的一些值,但我认为这个问题的库知识没有实际意义。

我有以下三重观察者:

// Reactive Mouse Positionining
const { x, y } = useMouse()

//  Detect if the Mouse has been pressed:
const { pressed } = useMousePressed({ 
  target: celestiaSkyViewerRoot, 
  touch: true 
})

watch([pressed, x, y], ([newPressed, newX, newY], [prevPressed, prevX, prevY]) => {
  if (showConstellations.value) {
    if (!newPressed && newX !== prevX) {
      activeConstellation.value = getActiveConstellation(newX, newY)
    }
  }

  dragging.value = pressed.value

  if (newPressed && newX !== prevX) {
    azimuthalOffset.value -= (newX - prevX) / 6
  }
})

但是,我看到出现以下 Typescript 错误:

对于newX,对应行:activeConstellation.value = getActiveConstellation(newX, newY)

Argument of type 'number | boolean' is not assignable to parameter of type 'number'. Type 'boolean' is not assignable to type 'number'.

对于newX,相关行:azimuthalOffset.value -= (newX - prevX) / 6

The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

但是,Vetur 仅显示 newY 的问题,与以下行有关:azimuthalOffset.value -= (newX - prevX) / 6:

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

有谁知道可能的解决方案吗?从本质上讲,这些错误正在停止重新加载我的开发服务器......并且它正在成为一个令人沮丧的开发瓶颈......

我找不到该函数的类型定义,而且您没有提供有效示例,所以我只能猜测:

错误说 newXnewYprevXprevY 的类型是 number | boolean,但我无法告诉您原因。按照您编写代码的方式,您希望它们仅 number

三种解决方案的行为都略有不同,但它们都应该使用 typescript 进行编译:

如果任何变量不是number:

,则不要进一步执行
watch([pressed, x, y], ([newPressed, newX, newY], [prevPressed, prevX, prevY]) => {
  if (typeof newX !== 'number' || typeof newY !== 'number' ||
      typeof prevX !== 'number' || typeof prevY !== 'number') return;
  if (showConstellations.value) {
  ...

如果变量不是 number 类型,则使用默认值:

watch([pressed, x, y], ([newPressed, newX, newY], [prevPressed, prevX, prevY]) => {
  if (typeof newX !== 'number') newX = 0;
  if (typeof newY !== 'number') newY = 0;
  if (typeof prevX !== 'number') prevX = 0;
  if (typeof prevY !== 'number') prevY = 0;
  if (showConstellations.value) {
  ...

强制这些变量为 number。如果这些变量中的任何一个实际上可以是 boolean(我不确定),那么在这种情况下,这将导致意外行为:

watch([pressed, x, y], ([newPressed, newX, newY], [prevPressed, prevX, prevY]) => {
  ...
    activeConstellation.value = getActiveConstellation(newX as number, newY as number);
  ...
    azimuthalOffset.value -= ((newX as number) - (prevX as number)) / 6
  

如果有人像我一样遇到这个问题,这是以下解决方案,无需根据上述答案检查任何类型:

watch([pressed, x, y] as const, ([newPressed, newX, newY], [_, prevX, prevY]) => {
   ... // do something here
})

因此,您只需要投射 Vue 3 观察器多个数组:[] as const.