jyurek
jyurek

Reputation: 1177

Undefined TypeScript enum at compile time

I have an enum defined in types.ts:

export enum Handedness {
  Left,
  Right,
  Both,
}

export type State = {
  count: number
  handedness: Handedness
}

and I have an object being initialized in state.ts:

import { State, Handedness } from './types'

export const initial: State = {
  count: 0,
  handedness: Handedness.Both
}

When I run tests (via jest) for this project, state.ts generates an error TypeError: Cannot read property 'Both' of undefined, telling me that Handedness isn't defined at the time it's referenced. But I'm exporting it from its module and importing it before I use it... so it should be defined.

I've found other similar questions asking about undefined enums, but they seem to all be asking about runtime. This is a compile time problem as far as I can tell.

I don't see what I would be doing wrong here. I import other types in other places without issue. But this enum simply doesn't want to work. What is going on here and how can I work around it?

Upvotes: 19

Views: 15519

Answers (5)

Matteus Barbosa
Matteus Barbosa

Reputation: 2735

Object.entries does not work over enums. use for instead:

for (const cor in Payment_Corresponding_Invoice_Status) {
      if (cor[0] === statusEnumKey) {
        correspondingInvoiceValue = cor[1];
        break;
      }
}

Upvotes: 0

Jasper Croome
Jasper Croome

Reputation: 153

Similar issue here, but a slightly different cause & solution. Posting here in hopes that this helps others.

  1. I was defining my enum in a file /auth/types.ts:
....
export enum SampleEnum {
    FIRST = 1,
    SECOND = 2
}
  1. I was then exporting my types en-masse from /auth/index.ts:
export * from './types;
  1. Finally, I was importing this from the parent directory elsewhere in the app:
import { SampleEnum } from './auth'
...

const someOtherObject = {
  place: SampleEnum.FIRST
}

Running Jest, I was getting the TypeError: Cannot read property 'FIRST' of undefined error, even when the code compiled just fine.

To solve this, I switched my import statement to

import { SampleEnum } from './auth/types'

Upvotes: 6

benmneb
benmneb

Reputation: 2303

You can also try using const enums.

So change:

export enum Whatever { ... }

to

export const enum Whatever { ... }

Apparently as of ts-jest version 23.10 you can just do this. Much better!

Upvotes: 10

MiFr
MiFr

Reputation: 81

I encountered similar error while running my code with Jest. The issue was caused by a React component that imported an enum type from a module which was also being mocked with jest.mock. I fixed the issue by using jest.spyOn for method that I needed instead of whole module.

from: jest.mock("example/path", () => ({ useExampleMethod: () => {...

to: import * as exampleModule from "example/path"; jest.spyOn(exampleModule , 'useExampleMethod').mockReturnValue({...

Upvotes: 8

jyurek
jyurek

Reputation: 1177

Well, this isn't a way to get this to work, but this GitHub PR explains that ts-jest won't support enums that work like this. I've changed all uses to (e.g.) ("both" as Handedness) and it works. So, that's not an explanation, it's a workaround.

Upvotes: 17

Related Questions