14

I have the following TypeScript enum:

enum Country {
    BR = "Brazil",
    NO = "Norway"
}

Then imagine I have a method that takes a Country as an argument, like so:

someFunc = (country: Country): void => {
    console.log(country) //Will print "Brazil" if country = Country.BR
    console.log(Country[country]) //Same as above
    console.log(???) //I want to print "BR" if country = Country.BR
}

How do I solve the third console.log statement?

How do I get a hold of the enum key?

Regards

Robin Jonsson
  • 2,761
  • 3
  • 22
  • 42

4 Answers4

18

Under the enum constrution you get something like this

Country["BR"] = "Brazil";
Country["NO"] = "Norway";

which is a simple object.

By default you can't get the keys of your enum. But you can iterate over the keys manually and try to find that one.

enum Country {
    BR = "Brazil",
    NO = "Norway"
}

console.log(Object.keys(Country).find(key => Country[key] === country))
Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
4

ts-enum-util (github, npm) supports reverse lookup of value->key for string enums, compile time type safety, and run-time validation.

import {$enum} from "ts-enum-util";

enum Country {
    BR = "Brazil",
    NO = "Norway"
}

someFunc = (country: Country): void => {
    // throws an error if the value of "country" at run time is
    // not "Brazil" or "Norway".  
    // type of "name": ("BR" | "NO")
    const name = $enum(Country).getKeyOrThrow(country);
}
Jeff Lau
  • 433
  • 4
  • 4
0

First you need to understand what is the js code for

enum Country {
    BR = "brazil",
    NO = "norway"
}

Its simply

var Country;
(function (Country) {
    Country["BR"] = "brazil";
    Country["NO"] = "norway";
})(Country || (Country = {}));

So basically it's an object with "BR" and "NO" as keys. and assuming we know how to find key from value in object. Check this . Using same

enum Country {
    BR = "brazil",
    NO = "norway"
}

namespace Country {
    export function getEnum(c: string): Country | undefined {
        if(!c) return undefined;
        const cLowerCase = c.toLowerCase();
        return Object.keys(Country).find(k => Country[k as keyof typeof Country] === cLowerCase) as Country
    }
}


console.log(Country.getEnum('test'))

console.log(Country.getEnum('Brazil'))

console.log(Country.getEnum('norway'))

If you are wondering why we used keyof typeof check this answer

In case you have lots of keys in enum you can use map to store reverse mapping and use that

Dhruv Pal
  • 849
  • 2
  • 10
  • 25
-1

I often use a plain JavaScript object instead of an enum, and use the keyof operator for type safety on its keys:

const CountryMap = {
    BR: "Brazil",
    NO: "Norway"
};

// equivalent to: type Country = 'BR' | 'NO';
type Country = keyof typeof CountryMap;

const someFunc = (country: Country): void => {
    console.log(country);
}
Robert Penner
  • 6,148
  • 1
  • 17
  • 18