Ts-jest: Issues with exporting and importing enums

Created on 28 Jul 2017  Â·  24Comments  Â·  Source: kulshekhar/ts-jest

TypeScript Version: 2.4.1

Code

file1.ts
export enum Colors {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE"
}

export enum Numbers {
  ONE = 1,
  TWO = 2
}

file2.ts
import { Colors, Numbers } from "./file1";

Expected behavior:
Colors and Numbers should not be undefined in file2.
Colors should be:

{
  Red: "RED",
  Green: "GREEN",
  Blue: "BLUE"
}

Numbers should be

{
  ONE: 1,
  TWO: 2
  1: "ONE"
  2: "TWO"
}

Actual behavior:
Colors and Numbers are undefined.
Any enum entry requested fail with "Cannot read property 'enum entry' of undefined".
It seems that this only occurs in case of a circular dependency.
If you remove the circular dependency everything seems to work fine.

Needs More Info

Most helpful comment

Why is it closed? I can't use exported enum in my tests

actions.ts:

export const enum DefinitionActionType {
    LOADING_DEFINITIONS = 'definitions/LOADING_DEFINITIONS',
    LOADED_DEFINITIONS = 'definitions/LOADED_DEFINITIONS',
}

When running normally it's fine, but when i run tests it fails:

 FAIL  src/reducers/definitions/reducer.test.ts
  â—Ź Test suite failed to run

    TypeError: Cannot read property 'LOADING_DEFINITIONS' of undefined

      25 | export function reducer(state = initialState, action: DefinitionActions): State {
      26 |     switch (action.type) {
    > 27 |         case DefinitionActionType.LOADING_DEFINITIONS:
         |                                       ^
      28 |             return {

All 24 comments

@glazar is this similar to #112 ?

If not, would it be possible for you to create a minimal repo that reproduces this?

@kulshekhar
I do not know whether this is related to #112 or is another issue altogether.

I have created a small repo reproducing this issue.
Please have a look and let me know what you think.

This issue only happens for us only when running the unit tests.
We have worked around this issue by removing the circular dependency.
The problem is not visible when the code is bundled using webpack with ts-loader.

Thanks for the repo. I was able to replicate this issue and dig into it a bit.

I think that this comment in the Typescript repo explains the cause of this issue.

Given that this is more of a Typescript issue, I'm not sure there's much we can do here

From that comment, it appears that the TypeScript team has no intention of fixing this, and I don't really see how they could given that transpileModule has no consistently reliable way to resolve imports and access the enum definitions.

As this issue comment suggests, it isn't always safe to use transpileModule. I certainly understand the performance reasons why transpileModule was chosen for the preprocessor, though. The only solution I can think of would be to do a full compile ahead of time and then serve the transpiled JavaScript files as Jest requests them. That is not a trivial change, of course, and would require having a watch process in place as well.

Would it be workable to change the preprocessor to use a different compiler api - but just passing in the test file and a preconfigured list of files containing const enums? Or would that still kill performance?

I remember a comment in another issue which suggested they rewrote the const enums after compilation using a webpack plugin - maybe that would be more viable?

@rikkit if there's a workable solution, we can find a way to get that in

faced with same problem. But not with enums but with using my library (https://github.com/goloveychuk/tsruntime) which uses custom transformers api.
It emits types metadata and requires types from imported module. So it's any everywhere.
So, as I see, two options to workaround
1) run program.emit with filelist of all files. But this will affect performance since it will compile same files many times.
2) use LanguageServiceHost compiler api, and compile all files before jest stage starts.

https://github.com/goloveychuk/awesome-ts-jest
Proof of concept, which solves problem with imported enums and custom transformers.
With smart files updating (versioning) it should work pretty fast.

This might be solved by #505

You can test with beta version (see #697) which handles const enum and others thanks to the language service.

I faced the same problem with enum in unit tests. The problem was the services with the enum var were mocked, and the mock did not have the enum var.
The solution was copy the enum also in the mocked service and export it so the classes that used the service can access to it.

on ServiceA.ts

export enum Colors {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE"
}

and also on ServiceAMock.ts

export enum Colors {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE"
}

I had the same problem.
Here is what helped me:

  1. Make enum const.
    export const enum OneTwoThreeEnum { One = 'one', Two = 'two', Three = 'three' }
  2. Use it like this:
    const something = "One" as OneTwoThreeEnum.One

@yoasia This issue is fixed with version 23.10 - try upgrading if you haven't already.

I can confirm this is still an issue for version "24.0.2".

Any update on this once, we're still facing the issue in our Vue project?

What's the issue @germain-receeve @thefill ? 23.10 works for me, referencing const enums in test files with no problem. What's the difference?

To give a bit more context, we had an issue with one of our dependency ,for the example let's call itDEPENDENCY_NAME, that wouldn't compile properly when running tests.

We ended up solving the issue by updating our jest.config.js file: we added core-js to setup files and isolated modules from ts jest.

  setupFiles: ["core-js"],
  transformIgnorePatterns: ["/node_modules/(?!(DEPENDENCY_NAME)/)"],
  globals: {
    "ts-jest": {
      isolatedModules: true
    }
  }

Hope this can help other people!

Why is it closed? I can't use exported enum in my tests

actions.ts:

export const enum DefinitionActionType {
    LOADING_DEFINITIONS = 'definitions/LOADING_DEFINITIONS',
    LOADED_DEFINITIONS = 'definitions/LOADED_DEFINITIONS',
}

When running normally it's fine, but when i run tests it fails:

 FAIL  src/reducers/definitions/reducer.test.ts
  â—Ź Test suite failed to run

    TypeError: Cannot read property 'LOADING_DEFINITIONS' of undefined

      25 | export function reducer(state = initialState, action: DefinitionActions): State {
      26 |     switch (action.type) {
    > 27 |         case DefinitionActionType.LOADING_DEFINITIONS:
         |                                       ^
      28 |             return {

I'm seeing the same problem with version 24.0.2.

Seems to only happen when isolatedModules: true is used, but we need this setting to improve performance issue (#1115).

I found a workaround that sort of makes things okay:

It works if you have a module file that _only_ exports enums

     jest": "^24.9.0",
    "ts-jest": "^24.2.0",
    "typescript": "^3.7.2"

There is a note that if using enum inside .d.ts won’t work, but const enum will work.

There is a note that if using enum inside .d.ts won’t work, but const enum will work.

i have same issue!

@ahnpnl @v7lin same here.

I'm seeing the same problem with version 24.0.2.

Seems to only happen when isolatedModules: true is used, but we need this setting to improve performance issue (#1115).

Const enum doesn’t work with isolatedModules: true because typescript transpile API doesn’t support it, you can check in the documentation.

@lucasriondel are you using isolatedModules: true ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stangerjm picture stangerjm  Â·  4Comments

Vinnl picture Vinnl  Â·  3Comments

qm3ster picture qm3ster  Â·  3Comments

AlexGellert picture AlexGellert  Â·  4Comments

japhar81 picture japhar81  Â·  3Comments