You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

TypeScript错误TS2339:跨类方法绑定上下文引发类型校验问题

解决TypeScript中绑定this后类型校验错误的问题

这个问题我之前也碰到过——TypeScript的静态类型检查没法自动识别bind(this)带来的this指向变更,所以会误判keyPress方法里的this类型。下面给你几个靠谱的解决办法:

方法1:显式指定keyPress方法的this类型

TypeScript支持在函数的第一个参数位置声明this的类型,用来告诉编译器这个函数运行时的this指向。你可以修改DomService里的keyPress方法:

// 在DomService中修改keyPress方法
keyPress(this: ModalService, event: KeyboardEvent) {
  if (event.which === key.escape) {
    event.preventDefault();
    this.hide(); // 现在TS知道this是ModalService,不会报错了
  }
}

这样做的好处是从根源上解决类型问题,让TS明确知道这个方法被调用时的this上下文。如果这个keyPress方法本来就是专门给ModalService使用的,这是最干净的方案。

方法2:在ModalService中包装一个中间函数

如果不想修改DomService的代码,可以在ModalService里写一个箭头函数作为中转,利用箭头函数自动绑定当前this的特性,再通过callthis传给keyPress

// 在ModalService内部定义
private handleEscapeKey = (event: KeyboardEvent) => {
  // 用call指定this为ModalService实例
  this.domService.keyPress.call(this, event);
};

// 绑定事件时用这个中间函数
document.body.addEventListener('focus', this.handleEscapeKey, true);

这种方式不需要改动DomService,把上下文绑定的逻辑封装在ModalService内部,解耦性更好,而且TS能完美识别this的类型。

方法3:使用类型断言绕过检查(不推荐)

如果以上两种方法都不适用,你可以用类型断言强制告诉TS绑定后的函数类型:

document.body.addEventListener(
  'focus',
  // 断言为(event: KeyboardEvent) => void,让TS忽略this类型检查
  this.domService.keyPress.bind(this) as (event: KeyboardEvent) => void,
  true
);

不过这种方法相当于关闭了TS对这段代码的类型校验,失去了TypeScript的类型安全优势,除非万不得已,尽量不要用。

内容的提问来源于stack exchange,提问作者Kolby

火山引擎 最新活动