Enum type not defined at runtime

Typescript

Typescript Problem Overview


I have a problem where the Typescript compiler compiles my code successfully, yet the runtime gives me undefined type errors.

In my app I created a types.ts file with some things shared between multiple other ts files. It contains a string enum like:

enum MyEnum {
  One = "one";
  Two = "two";
}

When I define it like this. The compiler lets me use it in other ts files, and appears to be happy. However, at runtime I get the error "MyEnum is not defined".

I know of two ways to solve this:

  1. Define the enum in the file where it is used. But I don't think this will solve anything for other files that want to use it.
  2. Use "export" in the types.ts file, and import every type explicitly everywhere it is used.

I am quite new to Typescript, and I feel I might be misunderstanding something fundamental.

First, I don't get why the Typescript compiler happily compiles my code if there's going to be a runtime error. I would understand it if I had used the declare keyword, telling the compiler that something should be available at runtime, but in this case I don't see why it should assume that the enum comes from anywhere else then the types.ts file.

Second, I would like to define types somewhere globally in my app and have them be available everywhere without having to import them every time I used them. How do I accomplish this? Or is this maybe considered bad practice?

I am using Typescript 2.6 and my config looks like this:

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es6",
    "module": "commonjs",
    "lib": ["es6", "es7", "esnext"],

    "sourceMap": true /* Generates corresponding '.map' file. */,
    "outDir": "build" /* Redirect output structure to the directory. */,
    "removeComments": true /* Do not emit comments to output. */,

    /* Strict Type-Checking Options */
    "strict": true /* Enable all strict type-checking options. */,

    /* Additional Checks */
    "noUnusedLocals": true /* Report errors on unused locals. */,
    "noUnusedParameters": true /* Report errors on unused parameters. */,
    "noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
    "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,

    "plugins": [{ "name": "tslint-language-service" }],
    "skipLibCheck": true // because firebase-sdk has wrong type files now (Nov 18)
  },
  "include": ["src/**/*"],
  "exclude": ["build"]
}

Typescript Solutions


Solution 1 - Typescript

There's another way you can do this. If you don't want to export your enum you can define it as a const enum

const enum MyEnum {
   One = "one";
   Two = "two";
}

These are inlined by the compiler and are completely removed during compilation.

Solution 2 - Typescript

In my case of undefined enum, it turned out it's because of circular import:

export enum A {...} defined in file a.ts, export const b = ... defined in file b.ts;

import {A} from './a.ts' in b.ts, while import {b} from './b.ts' in a.ts.

The error was gone after removing circular imports.

Solution 3 - Typescript

I had the same problem when imported re-exported enum. It caused runtime error.

layout.ts

export enum Part { Column, Row }

index.ts

export * from './layout'

component.ts

import { Part  } from '../entities' // This causes error
import { Part } from '../entities/layout' // This works

Solution 4 - Typescript

I had this issue because I used declare in

export declare enum SomeEnum

Instead of

export enum SomeEnum

Solution 5 - Typescript

For us it turned out that simply restarting the application solved the problem. (Nativescript app)

Solution 6 - Typescript

I had this error and it went away as soon as I used the export keyword, i.e.

export enum MyEnum {
  One = "one";
  Two = "two";
}

And make sure you import it in the files where you are using it as well, i.e.

import { MyEnum } from '../types.ts';

I found that when I declared the enum without the export keyword, I could still reference the enum without importing it in other files without a compiler error - it was only at runtime the undefined exception was then thrown.

Solution 7 - Typescript

Here is my case, when I add a new enum to enum.ts file like this:

enum.ts:

enum RotateMode {
  UNKNOWN = 'UNKNOWN',
  OPTIMIZE = 'OPTIMIZE',
  ROTATE_FOREVER = 'ROTATE_FOREVER'
}

export { RotateMode };

I didn't run tsc to compile this file again. This cause the enum.js file doesn't have the RotateMode enum

enum.js:

// old file doesn't have the RotateMode enum

Then, I import the RotateMode enum to my index.ts file:

import { RotateMode } from './enum';

console.log(`RotateMode: ${JSON.stringify(RotateMode)}`);

The result is:

RotateMode: undefined

Somehow, the import syntax will import from .js file with high priority.

So, DON'T forget to compile the ts file after you add something new

Solution 8 - Typescript

I may be late to the party but beware of any @ts-ignore lines in the files blamed by the error stack.

My issue was that, after a pretty big refactoring, the import to the enum was cleaned by an IDE shortcut and the compiler couldn't detect it as missing because of the ts-ignore annotation which was targeted at something else (alas, on the same line).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThijs KoerselmanView Question on Stackoverflow
Solution 1 - TypescriptMatt BView Answer on Stackoverflow
Solution 2 - TypescriptkeosView Answer on Stackoverflow
Solution 3 - Typescriptsad comradeView Answer on Stackoverflow
Solution 4 - TypescriptSteffsView Answer on Stackoverflow
Solution 5 - TypescriptBakiView Answer on Stackoverflow
Solution 6 - TypescriptCiaran GallagherView Answer on Stackoverflow
Solution 7 - Typescriptslideshowp2View Answer on Stackoverflow
Solution 8 - Typescriptthat_random_pixelView Answer on Stackoverflow