TypeScript / ReactJS / setTimeout:'this' 隐式具有类型 'any' 因为它没有类型 annotation.ts

TypeScript / ReactJS / setTimeout: 'this' implicitly has type 'any' because it does not have a type annotation.ts

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

React 应用程序中存在导致立即调用 setTimeout 的错误,然后我在此处的此答案中找到了修复:

下面是我的代码,但我在 this.resetNotification

上的 this 上收到以下打字稿错误

any 'this' implicitly has type 'any' because it does not have a type annotation.ts(2683) Board.tsx(158, 7): An outer value of 'this' is shadowed by this container.

@bind
resetNotification(): any {
  console.log('resetNotification...');
  this.setState({ notificationClass: 'spin-in-notification' });
  this.props.setNotification('', false);
}

@bind
private handleNotificationClick() {
  this.setState({ notificationClass: 'slide-out-bck-top' });

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

使用 setTimeout 上的箭头函数为 heredate parents props

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

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

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

由于文件名为 Board.tsx,我假设您的组件是 <Board>。如果不是,请更改 this.

的类型注释

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

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

在你的情况下,你提到的 “错误” 基本上是同一件事。
当您注册 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,因为它没有 return 任何东西。