Ts-jest: ReferenceError: PointerEvent is not defined

Created on 20 Mar 2019  路  11Comments  路  Source: kulshekhar/ts-jest

Issue :

After upgrading to Jest 24, I get this Typescript error:

ReferenceError: PointerEvent is not defined

I use a tsconfig.spec.json (which seems to be loaded by ts-jest) which contains "lib": ["es2017", "dom"] in compilerOptions.

Expected behavior :

I expect PointerEvent to be defined, as it is part of the TypeScript dom lib.

Most helpful comment

Summarizing the discussion in https://github.com/thymikee/jest-preset-angular/issues/245:

  • Combination of Method Decorator and PointerEvent in the method signature will throw this error
  • Angular is not required to trigger the error
  • tsconfig.spec.json is configured with "types": ["dom"]
  • Other DOM-types like other events do not throw an error
  • any Decorator could be used
  • IDE (VSCode with TS) does not throw error

Minimal reproduction:

export function Decorator() {
  return (...args) => {};
}

class Test {
  @Decorator()
  decoratedMethodWithPointerEventType(event: PointerEvent) { }
}

describe('DOM PointerEvent and Decorators', () => {
  it('should not throw when combining a decorator with the DOM type PointerEvent', () => {
    const t = new Test()
    expect(t).toBeTruthy()
  });
})

All 11 comments

Summarizing the discussion in https://github.com/thymikee/jest-preset-angular/issues/245:

  • Combination of Method Decorator and PointerEvent in the method signature will throw this error
  • Angular is not required to trigger the error
  • tsconfig.spec.json is configured with "types": ["dom"]
  • Other DOM-types like other events do not throw an error
  • any Decorator could be used
  • IDE (VSCode with TS) does not throw error

Minimal reproduction:

export function Decorator() {
  return (...args) => {};
}

class Test {
  @Decorator()
  decoratedMethodWithPointerEventType(event: PointerEvent) { }
}

describe('DOM PointerEvent and Decorators', () => {
  it('should not throw when combining a decorator with the DOM type PointerEvent', () => {
    const t = new Test()
    expect(t).toBeTruthy()
  });
})

Same happens with BeforeUnloadEvent.

@kulshekhar could you take a look at this?

surprisingly the issue doesn't happen to a newly generated Vue project, but it failed with my Angular project. I have Vue project here

In our project, this is blocking our upgrade to Jest 24. Is this issue so rare? 馃槈

There are two reasonably easy workarounds if you're interested:

  • Create a placeholder type: type MyPointerEvent = PointerEvent;
  • Let the event argument have type any and reassign it in the body of the method: const evt: PointerEvent = event;

I gave it another shot and setup a clean ts project with jest and ts-jest.
First I realized it only if the tsconfig setting emitDecoratorMetadata is set, the error appears.

I compiled the decorated class using tsc and understood that tsc bakes in the type as value in the metadata decorator:

    TestClass.prototype.decoratedMethodWithPointerEventType = function (event) { };
    __decorate([
        decorator_1.Decorator(),
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [PointerEvent]),
        __metadata("design:returntype", void 0)
    ], TestClass.prototype, "decoratedMethodWithPointerEventType");
    return TestClass;

I let jest run the compiled classes and it did not fail, when I exchanged the PointerEvent with e. g. MouseEvent.

This results in the following minimal failing test setup, not even including any ts and ts-jest:

//some.spec.js
it('test DOM events PointerEvent and BeforeUnloadEvent', () => {
    console.log('ME', MouseEvent)
    console.log('BUE', BeforeUnloadEvent)
    console.log('PE', PointerEvent)
})

I will pass this to jest now in a new issue.

I realized, this is not in jest's hands. Jest uses JSDOM to run the tests, and after a quick check I saw there is already an issue opened in JSDOM to implement PointerEvent.

Basically the Constructor is missing: window.PointerEvent.

I suggest everyone interested in this to subscribe to this issue or even provide a PR to JSDOM:
https://github.com/jsdom/jsdom/issues/2527

Once this is implemented in jsdom, it might take some additional time for jest to provide the test environment.

Until then this patching can be used:

// setupEvents.js
window.PointerEvent = function(type, eventInitDict) {}
window.BeforeUnloadEvent = function() {}

It has to be registered in jest.config.js

module.exports = {
  setupFilesAfterEnv: ['./setupEvents']
}

@ahnpnl I think this issue can be closed, there is nothing ts-jest can do about it.

Thanks for investigating! I still don鈥檛 really understand why this wasn鈥檛 an issue on Jest 23. Also, I use it as a TypeScript interface, not as a runtime JS class.

Edit: is that because Jest 23 doesn鈥檛 use decorator metadata emitting?

Through the decorator it becomes a runtime class. If available TS will reference the constructor. And in the TS types the constructor is also referenced (new()) so when emitting metadata it will insert the constructor in JS.

Yeah, might be! I did not know they did not emit metadata before. Or maybe ts-jest did not do it before 23.10?

Running the minimal JS example also fails on jest@23.

@wtho @dirkluijk i think because 23.10 started using typescript compiler api which wasn鈥檛 used < 23.10 so there is no decorator emitted before.

I guess this issue can be closed.

Yeah, it's not related to ts-jest, this issue can be closed.

It is jsdom, which is not up-to-date with DOM specifications. Track this issue for more info https://github.com/jsdom/jsdom/issues/2527.

See the comment above for a workaround.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

remcohaszing picture remcohaszing  路  4Comments

stephenotalora picture stephenotalora  路  3Comments

japhar81 picture japhar81  路  3Comments

Vinnl picture Vinnl  路  3Comments

RiJung picture RiJung  路  4Comments