Enums in Typescript

Enums allow you to create a type with a fixed list of possible values. They are unordered data structures that map keys to values, similar to objects with fixed keys. The values can be numbers or strings. If no values are assigned, then they are inferred.

enum Language {
	English,
	Spanish,
	French
}

The convention is to use uppercase, singular names for enums. Their keys should also be uppercase.

You can either set the values or they will be inferred with the same numbers as below.

enum Language {
	English = 0,
	Spanish = 1,
	French = 2
}

Retrieving values

You can use dot or bracket notation just like with objects.

	let en = Language.English
	let fr = Language['French']

Declaration merging

Typescript will merge enums split over multiple declarations just make sure to explicitly set the values because it can only infer them for the first declaration.

enum Language {
	English = 0,
	Spanish = 1
}

//...
enum Language {
	French = 2
}

Const enums

By default Typescript will allow you to access non existent keys on an enum like Language[14].

To prevent this unsafe behavior you can use const enum:

const enum Language {
	English,
	Spanish
}

let en = Language.English // type of Language
let fr = Language.French // Error, the property French doesn't exist on type Language
let en2 = Language[0] // TS won't allow you to access English with a numeric key anymore because of const

Preserving const enums

By default Typescript doesn’t generate code for const enums when it compiles to JS, it will just inline the values like 1 for Spanish, wherever that values shows up.

This can lead to safety issues when using 3rd party code so it’s a good idea to use the preserveConstEnums flag:

{
	"compilerOptions": {
		"preserveConstEnums": true
	}
}

Stick to string values

Another pesky problem that might pop up is when you create a function that’s set to accept an enum type and that enum doesn’t have the values explicitly set.

const enum Flippable {
	Burger,
	Table
}

function flip(f: Flippable) {
	return 'flipped'
}

flip(Flippable.Burger) // flipped
flip(14) // flipped

The last line shouldn’t work but it does so to fix this we assign strings instead of numbers:

const enum Flippable {
	Burger = 'Burger',
	Table = 'Table'
}

function flip(f: Flippable) {
	return 'flipped'
}

flip(Flippable.Burger) // flipped
flip(14) // 14 is not assignable to Flippable
flip('Cat') // 'Hat' is not assignable to Flippable

This is a summary compiled from a great book I’ve been reading, “Programming Typescript” - Boris Cherny. I bought the paperback but it’s also available as part of the Safari Learning subscriptions which I highly recommend. I read most tech books online on their platform and only buy the classicals in paper form.