开发者问题收集

`e: TouchEvent` 的 `@HostListener` 导致 Firefox 崩溃并出现“ReferenceError: TouchEvent 未定义”。

2018-07-01
1794

使用 @HostListener 并将事件参数明确类型为 TouchEvent ,会导致 Firefox 崩溃并显示以下错误消息:

ReferenceError: TouchEvent is not defined.

示例:

@HostListener('touchstart', ['$event']) // or 'touchend', 'touchmove'
onTouchStart(e: TouchEvent): void {}

我可以想出几种方法来防止这种情况发生:

  • 使用 e: TouchEvent | anye: any (或者根本不指定类型)
  • 使用 elRef.nativeElement.addEventListener('touchstart', (e: TouchEvent) => {})
  • 使用 Observable.fromEvent(elRef.nativeElement, 'touchstart').subscribe((e: TouchEvent) => {})

但使用 any| any 似乎是一种 hack,而其他两个选项没有利用框架。 是否有其他更好、更安全的方法来处理此问题?如果没有,哪种方法更可取?

(也许有人可以解释 Angular 实际上在做什么,以及为什么只有当事件明确类型为 TouchEvent 时才会发生此错误...)


编辑:此问题在 Angular 7 中仍然存在。 编辑: 此问题显然已在 Angular 6 中得到修复。

2个回答

当方法上有装饰器时,typescript 编译器会将参数类型存储在元数据中,这在桌面版 Firefox 中会失败,因为 TouchEvent 未在此处定义。可以通过使用存根填充缺失的类型来解决此问题。只需将以下代码添加到 polyfills.ts

for (const type of ['TouchEvent']) {
    if (typeof window[type] === 'undefined') {
        window[type] = function () { };
    }
}

要填充其他类型,请将它们添加到列表中。请注意 - 这可能会破坏通过检测 window.TouchEvent 来检查触摸事件是否存在的代码。

无论如何,该问题似乎只发生在 JIT 编译器中,因此它可能会随着 Ivy 而消失。

IztokK
2020-10-28

您可以告诉 Angular 不要在 tsconfig.json 中发出装饰器元数据: "emitDecoratorMetadata": false

waterplea
2019-03-19