多个 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.
有谁知道可能的解决方案吗?从本质上讲,这些错误正在停止重新加载我的开发服务器......并且它正在成为一个令人沮丧的开发瓶颈......
我找不到该函数的类型定义,而且您没有提供有效示例,所以我只能猜测:
错误说 newX
、newY
、prevX
、prevY
的类型是 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
.
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.
有谁知道可能的解决方案吗?从本质上讲,这些错误正在停止重新加载我的开发服务器......并且它正在成为一个令人沮丧的开发瓶颈......
我找不到该函数的类型定义,而且您没有提供有效示例,所以我只能猜测:
错误说 newX
、newY
、prevX
、prevY
的类型是 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
.