People use string literal enums because numeric enums are completely backwards. Arbitrary numbers can be assigned to enums types, even when they are out of range. So numeric enum type is nothing more than just a number. Did something change since then?
When I read this title, I was ready to come out swinging against enums since, as you point out, they're nearly never used in a way that gives them an advantage over, say, string literal unions. But you've described their use case really well!
Wait.. are people actually complaining about these things? You're correct about its intended use, I'd be heavily offended if someone actually spewed "const obj = {} is better" because that's apples and oranges, enums aren't meant to store lookup values. Enum exists to create type-correctness attached to a name rather than a value. They're designed to reduce human error on arbitrary values. It's best to think of an enum's values as being capable of changing every time the application restarts (even though in reality they don't unless the body of the enum is changed).
renkinjutsushi
swe
What if the UI would send 'Go' to the API but the instruction would need to be translated into the enum value? In this case it would be 2.
Would we use a reverse map for the instructions?
i.e.
"const fromInstructions = new Map([ ["Stop", TrafficLight.Red], ["Slow down", TrafficLight.Yellow], ["Go", TrafficLight.Green], ]);"
Or do you reckon it would be ok keeping them in the same instructions map?