Wednesday, August 03, 2016

TypeScript const enums

In my previous post I mentioned that if you make an enum const then you don't get the run time bidirectional mapping between numbers and names. It turns out that's not quite true.

If you turn on the preserveConstEnums compiler option (set it to true) then TypeScript still emits the mapping object, even though it still in-lines the enum values.

That seems like the best of both worlds. But I couldn't get it to work. If you try to use the mapping, you get:
import { Token } from "./tokens"
...
Tokens[token]

=> A const enum member can only be accessed using a string literal.
I searched online and found some suggestions to type assert to "any", but it didn't work.
import { Token } from "./tokens"
...
(Tokens as any)[token]

=> 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.
So I gave up and didn't use const.

Then I came across a slightly different type assertion that worked!
import * as tokens from "./tokens"
...
(tokens as any).Tokens[token]
As the saying goes: "All problems in computer science can be solved by another level of indirection"

Note: As is recommended, I'm using the newer "as" form of type assertions instead of the older <type> form.

No comments: