Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with exporting and importing enums #281

Closed
glazar opened this issue Jul 28, 2017 · 42 comments
Closed

Issues with exporting and importing enums #281

glazar opened this issue Jul 28, 2017 · 42 comments
Labels
🤷‍♂️ Needs More Info waiting for more information from author of the issue
Milestone

Comments

@glazar
Copy link

glazar commented Jul 28, 2017

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.

@kulshekhar
Copy link
Owner

@glazar is this similar to #112 ?

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

@glazar
Copy link
Author

glazar commented Jul 31, 2017

@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.

@kulshekhar
Copy link
Owner

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

@bencompton
Copy link

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.

@rikkit
Copy link
Contributor

rikkit commented Aug 30, 2017

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?

@kulshekhar
Copy link
Owner

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

@goloveychuk
Copy link

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.

@goloveychuk
Copy link

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.

kulshekhar added a commit that referenced this issue Apr 14, 2018
Add links for issues #112 and #281 in README.md
@GeeWee
Copy link
Collaborator

GeeWee commented May 5, 2018

This might be solved by #505

@huafu
Copy link
Collaborator

huafu commented Sep 2, 2018

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

@huafu huafu added the 🤷‍♂️ Needs More Info waiting for more information from author of the issue label Sep 8, 2018
@huafu huafu added this to the v23.10.0 milestone Sep 19, 2018
@huafu huafu closed this as completed Sep 19, 2018
@nikoremi97
Copy link

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"
}

@yoasia
Copy link

yoasia commented Jun 11, 2019

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

@rikkit
Copy link
Contributor

rikkit commented Jun 11, 2019

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

@thefill
Copy link

thefill commented Jun 25, 2019

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

@germain-receeve
Copy link

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

@rikkit
Copy link
Contributor

rikkit commented Oct 24, 2019

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?

@germain-receeve
Copy link

germain-receeve commented Oct 25, 2019

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!

@dskopa-softdev
Copy link

dskopa-softdev commented Oct 30, 2019

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 {

@jemerald
Copy link

jemerald commented Dec 2, 2019

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).

@cbaron
Copy link

cbaron commented Feb 19, 2020

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"

@ahnpnl
Copy link
Collaborator

ahnpnl commented Feb 19, 2020

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

@droplet-js
Copy link

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

i have same issue!

@lucasriondel
Copy link

@ahnpnl @v7lin same here.

@ahnpnl
Copy link
Collaborator

ahnpnl commented Apr 29, 2020

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 ?

neuberoliveira added a commit to neuberoliveira/pagarme-js-types that referenced this issue Sep 24, 2020
@safareli
Copy link

safareli commented Jan 5, 2021

I still have same issue. what's the solution and is it documented somewhere?

@ahnpnl
Copy link
Collaborator

ahnpnl commented Jan 5, 2021

@safareli are you using isolatedModules: true ?

@safareli
Copy link

safareli commented Jan 5, 2021

@ahnpnl, no I don't have it in my tsconfig.json (or any other place)

@ahnpnl
Copy link
Collaborator

ahnpnl commented Jan 5, 2021

I meant ts-jest option isolatedModules in your jest config.

If you have it as true, enum won't work. If you have it as false (default) it should work.

If you have it as false and it still doesn't work, you can share a repo so I can help.

@safareli
Copy link

safareli commented Jan 5, 2021

@ahnpnl 🤦 so the issue was that I had one file "foo.json" and "foo.ts" in same folder and when I was compiling using tsc foo.ts and checking output it was fine. But when jest was resolving import of "./foo" looks like it is first checking if .json exists which it was, so it was requiring the json file instead of the ts file, that's why I had the issue.

@DoctypeRosenthal
Copy link

@safareli you gave me the idea of checking this in my code because I had the same problem. Turns out we had too many index.ts which re-exported stuff from sub-modules. So I specified my inports in those modules where the error occured and voilá: fixed it!
eg.
import { crudEntityFactory, ReduxEntities, RootState } from '@core/data';
became
import { crudEntityFactory, ReduxEntities, RootState } from '@core/data/redux';

@zarnoevic
Copy link

I can confirm the issue remains in version "26.2.0".

@jdpaterson
Copy link

Experiencing this issue in "27.0.5" when exporting default const enums. Seems to work properly when just exporting default enums (not const)

@johny-nowotny
Copy link

Thank you for all suggestions, they solved my problem! I'll leave what helped me for others to find.
For me making the dependency tree a bit more granular helped, either:

  • mock definition require()-d in jest.mock() moved to a separate file (it was in a bundle with additional imports)
    or
  • importing the enum from a different file than re-exported index.ts

@njfix6
Copy link

njfix6 commented Sep 15, 2022

I am also still seeing this issue. I just isolatedModules: true and isolatedModules: false and still running into Cannot read properties of undefined (reading 'All') for both.

My enum that I am exporting is not with const:

export enum Type {
  All = 'All',
  Both = 'BOTH',
}

@gtwebsite
Copy link

Im using ts-jest 27.1.4, it still shows the error. isolatedModules doesnt affect any. im using export enum inside a d.ts file. I cannot changed this file because it's from codegen

@atheck
Copy link

atheck commented Oct 7, 2022

I have the same issue with an enum from a third-party package.

@Mnigos
Copy link

Mnigos commented Nov 5, 2022

same here

  ● Test suite failed to run

    TypeError: Cannot read properties of undefined (reading 'AUTH')

      4 |
      5 | @Module({
    > 6 |   imports: [RmqModule.register({ name: Services.AUTH })],
        |                                                 ^
      7 |   exports: [RmqModule],
      8 | })
      9 | export class AuthModule {}
export enum Services {
 AUTH = 'AUTH',
 STATISTICS = 'STATISTICS',
}

@hichemBAALI
Copy link

Hi people.

On my end the issue was only happening for .ts files and not for .tsx
I duplicated the declaration on the .ts files then the test passed.

@rubickecho
Copy link

yes, i have this problem too, but I don't know how to solve it either.

@MatejVukosav
Copy link

Just put enum in separate file. It works for me.

@Aure77
Copy link

Aure77 commented Sep 28, 2023

Still happen in ts-jest v29. Why is this issue closed ?

@christiangrothaus
Copy link

The only workaround I have found is to mock the enum in the test file and declare it as a object. Trying to mock it in anyway in a mock file failed to work and declaring it as an enum in the test file also failed to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤷‍♂️ Needs More Info waiting for more information from author of the issue
Projects
None yet
Development

No branches or pull requests