简体   繁体   中英

Why does Typescript think my enum is undefined?

I'm using Typescript, Redux, and React, all of which are new to me so this probably has a simple fix I'm just not seeing.

I have an actions.ts file which includes an enum like this:

export enum AnimalTypes {
    CAT = 'CAT',
    DOG = 'DOG'
}

I import it in my reducers.ts file and was trying to use it in a log statement like this:

import {AnimalTypes} from './actions';

export function someFunction() {
    // Print the word "CAT"
    console.log(AnimalTypes[AnimalTypes.CAT]);
}

I get the following error when I try to launch my site:

TypeError: Cannot read property 'CAT' of undefined
  at someFunction (reducer.ts:5)
  at combineReducers.js:20
  etc.

My IDE doesn't give me any errors and neither does TSLint. I've read a bunch online trying to find the answer but the closest I came was from someone who didn't have the "export" keyword on their enum and I do.

What could be going on here? I'd be grateful for any help.

Thank you.

EDIT: It's not the reverse mapping that it's having a problem with, rather any usage of the enum. That was just the shortest usage I could think of. I'm actually using it in a switch statement:

import {AnimalTypes} from './actions';

export function otherFunction(animal) {
    switch (animal.type) {
        case AnimalTypes.CAT:
            // Do stuff
}

When I build the above code, I get this error Uncaught TypeError: Cannot read property 'CAT' of undefined

This feature of typescript is called "reverse mapping", and per the documentation it is only supported with numeric enums. Here is the snippet from https://www.typescriptlang.org/docs/handbook/enums.html :

In addition to creating an object with property names for members, numeric enums members also get a reverse mapping from enum values to enum names.

I couldn't reproduce your exact case: I imported an enum in my reducer and created that exact function which logged the enum, and it worked.

However, I just ran into the same problem in a slightly different context: I added the import for my AppRoutes enum in my SideNav file. Inside the SideNav file, in a const popularArticles that mapped through some JSON and returned some TSX, when I tried to <NavLink to={AppRoutes.something}> I got "cannot read property something of undefined" even though hovering over AppRoutes.something in the IDE would show me the correct value from the correct source. I think this is a pretty similar case to yours so I hope my solution will help future readers running into this problem.

What solved it for me was to integrate the const popularArticles (which was outside the SideNav class) into a variable public popularArticles inside the class, just before the constructor. I don't know why but upon further experimentation I found that apparently you can't access the enum outside of a class or SFC...

What I did was this:

import {AnimalTypes} from './actions';

export function someFunction() {
    var animalTypesEnum = AnimalTypes;
    // Print the word "CAT"
    console.log(animalTypesEnum[animalTypesEnum.CAT]);
}

and it worked. TS v3.6.4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM