TypeScript / ReactJS / setTimeout:'this'隐式地具有'any'类型,因为它没有类型注释。

时间:2019-03-13 22:34:58

标签: javascript reactjs typescript settimeout next.js

在我的NextJS / React打字稿应用程序中,我正在使用setTimeout。

React应用程序中存在一个错误,该错误导致setTimeout立即被调用,然后我在此答案中找到了解决方法:ReactJS: setTimeout() not working?

下面是我的代码,但是我在this的{​​{1}}上遇到以下打字稿错误

  

任何   ``this''隐式地具有类型``any'',因为它没有类型注释.ts(2683)   Board.tsx(158,7):此容器遮盖了外部值“ this”。

this.resetNotification

enter image description here

3 个答案:

答案 0 :(得分:4)

使用setTimeout上的箭头功能针对此日期的父母道具

setTimeout(
  () => {
  this.resetNotification();
  }......

答案 1 :(得分:2)

如果您仍想使用function () {}语法,则可以将this作为函数的第一个参数以及类型注释一起传递。像这样:

  setTimeout(
    function(this: Board) {
      this.resetNotification();
    }
    .bind(this),
    500
  );

我假设由于文件名为Board.tsx,因此您的组件为<Board>。如果没有,请更改this的类型注释。

答案 2 :(得分:0)

只需将函数作为引用传递即可,无需将其包装在匿名函数中甚至绑定它,从而创建另一个函数。

setTimeout(this.resetNotification, 500);

React 立即调用 setTimeout 没有错误,所以如果你对此感到困惑,请考虑这个。

function doSomething() {/* */}

const a = doSomething() // immediately invokes and assigns a result
const b = doSomething   // stores a reference

// call later
const x = a() // error
const y = b() // invokes doSomething and assigns a result

在你的情况下,你提到的“bug”基本上是一样的。
当您注册 setTimeout 回调时,您错误地立即调用了它,而您应该传递对它的引用。

function doSomething() {/* */}

// wrong
setTimeout(doSomething(), 500) // This is basically the same as writing the `a` from above
setTimeout(a, 500)             // like this. See the problem? a() cannot be called later.

要修复它,您有三个选择。

  1. 传递引用
setTimeout(this.resetNotification, 500)
  1. 包裹在对this透明的匿名箭头函数中,
    意味着它捕获外部(父)this
    请注意,每次调用此函数时,它都会将您的函数包装在另一个函数中
setTimeout(() => this.resetNotification(), 500)
  1. 包装在一个标准的匿名函数中,但由于它带有自己的 this,您必须将其绑定到父函数的 this
    注意,这将你的函数包装在另一个函数中,然后绑定它,每次都会创建第三个函数
setTimeout(function(){this.resetNotification()}.bind(this), 500)

输入 setTimeout

setTimeout(callback, timeout?, param1?, param2?, ...)

人们似乎没有意识到 setTimeoutsetInterval 实际上接受可选的无限参数。原因是为了使调用回调更简单,而不是这样

setTimeout(
  function(){
    this.doSomething(true, "string", someVariable)
  }.bind(this),
  500
)

你可以写这个

setTimeout(this.doSomething, 500, true, "string", someVariable)

是不是很漂亮很优雅? ?


此外,您应该将 resetNotification() 函数的签名修正为 resetNotification(): void 而不是 :any,因为它不返回任何内容。