While working on my web app, I encountered a crash issue in Safari due to the type definition for a function referring to the TouchEvent
interface. This caused problems because the variable was directly emitted in decorator metadata in the compiled JS code and is not supported on desktop Safari (see more here).
Solving this particular instance was straightforward by using Event
instead of TouchEvent
. However, it got me thinking... Are there potentially other decorator metadata in my application that could be causing issues on untested browsers?
Below is an Angular 2 directive example that demonstrates the issue:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[touchTest]'
})
export class TouchTest {
constructor() { }
@HostListener('touchend', ['$event']) onTouchend(event: TouchEvent) {
console.log(event);
}
}
If you compile this with
tsc touch-test.ts --emitDecoratorMetadata --experimentalDecorators
, the generated output includes the following (full JS output can be viewed here):
__decorate([
core_1.HostListener('touchend', ['$event']),
__metadata("design:type", Function),
__metadata("design:paramtypes", [TouchEvent]),
__metadata("design:returntype", void 0)
], TouchTest.prototype, "onTouchend");
The use of TouchEvent
in the code throws an error of TouchEvent is not defined
on Safari.
I have observed that some parameter types, especially the ones explicitly imported, are emitted as Object
in the JS output, which is considered safe. Additionally, the interface TouchEvent
is defined in various .d.ts
files within the typescript
npm module, allowing me to use it without compile-time errors.
Is there a general guideline or rule I should follow to prevent such problems? It's possible that there might be a problematic setting in my development environment (I initially used angular2-webpack-starter), but after reviewing the tsconfig.json
and other relevant configuration files, nothing immediately stood out to me.