首页 > 解决方案 > 如何在 Vue2 中对去抖动的计算设置器进行类型转换?

问题描述

Vue:2.6.11
打字稿:3.9.3
Codesandbox:这里

这是我正在尝试做的简化版本:

<template>
  <input v-model="computedValue" type="number">
</template>
<script lang="ts">
  import Vue from 'vue';
  import { debounce } from 'lodash-es';

  export default Vue.extend({
    name: 'MyInput',
    props: {
      value: {
        type: Number,
        required: true
      }
    },
    computed: {
      computedValue: {
        get(): number {
          return this.value;
        },
        set: debounce(function(value) {
          this.$emit('update:value', value);
        }, 500)
      }
    }
  });
</script>

这被父母用作<my-input :value.sync="someProp" />. 它是更复杂的表单系统的一部分,具有不同类型的输入,配置驱动。但这与我提出的问题无关。当我不去抖动时,一切都按预期工作。如中,所有内容都已正确输入和推断。

我的问题是我不知道如何告诉 Typescript 将外部this投射到去抖动函数的 this 上,这debounce在引擎盖下是可以做到的。

实际的打字稿错误是:

TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.

错误截图

代码有效(计算的 setter 已去抖动),但 Typescript 抱怨不知道this 去抖动函数内部的内容。
如果我将 debounced 函数从普通函数更改为箭头函数,Typescript 不再对我咆哮(它现在知道是什么this),但代码停止工作。

有谁知道如何正确转换this去抖动函数内部的值?

注意:不建议在/* @ts-ignore */上面放置一行。这就是我目前正在做的事情。

另一个注意事项:我的猜测是我必须覆盖debounce当前来自的定义的类型@types/lodash-es,但我仍然不知道用什么替换它。

标签: typescriptvuejs2computed-propertiesdebounce

解决方案


在匿名函数中使用this总是很棘手,因为 的值this取决于函数的调用方式。Lodash 可能在这里做了正确的事情,this但 TS 不知道这一点。

最简单的解决方法通常是“捕获”this局部变量中的值,如下所示:

methods: {
  someMethod() {
    const self = this
    setTimeout(function() { self.doSomething() }, 500)
  }
}

这对于您的代码当然是不可能的,我认为您的代码还有一个问题,这就是您创建去抖动包装器的方式。它在 Vue 3 文档中有所暗示,但也适用于 Vue 2

这种方法对于重用的组件可能存在问题,因为它们都将共享相同的去抖动功能。

要解决这个问题(同时解决 TS 问题):

computed: {
      computedValue: {
        get(): number {
          return this.value;
        },
        set(value): void {
          this.debouncedSetter(value)
        }
      }
    },
created() {
  self = this
  this.debouncedSetter = debounce(function(value) {
    self.$emit('update:value', value);
  }, 500)
}

推荐阅读