Beginner’s TypeScript #tips

Nhan Nguyen
2 min readJan 24, 2024

Typescript enums and why we should avoid them

In the beginner’s code bases, we often use Typescript enums to store a bunch of constants.

export enum CompassDirection {
North, // 0
East, // 1
South, // 2
West, // 3
}

The above code creates a new type CompassDirection with four possible values: CompassDirection.North, CompassDirection.East, CompassDirection.South, and CompassDirection.West.

Each constant gets assigned a numerical value starting at 0, so in that example, CompassDirection.North is equal to 0, and CompassDirection.West is equal to 3.

These values can be customized, and we can use strings, objects, or anything we want instead of numbers:

export enum CompassDirection {
North = 'N',
East = 'E',
South = 'S',
West = 'W',
}

So Why should we avoid enums? 🤔

We should avoid enums because they are neither convenient nor performant. For instance, this is what the last example gets compiled into by the Typescript compiler:

var CompassDirection;
(function (CompassDirection) {
CompassDirection['North'] = 'N',
CompassDirection['East'] = 'E',
CompassDirection['South'] = 'S',
CompassDirection['West']= 'W',
})(CompassDirection || (CompassDirection = {}))

That is not pretty, and it comes at the extra cost of all that code being downloaded in the browser and then interpreted, which impacts performance.

Also, enums are not very convenient to be used in component templates. If we want to use an enum in a component template, we need this additional code to make that type accessible on the component instance:

export enum CompassDirection {
North = 'N',
East = 'E',
South = 'S',
West = 'W',
}

// In Angular Hello Component
@Component({...})
export class HelloComponent {
compassDirection = CompassDirection;
}

Instead, we could use a union type:

type CompassDirection = 'North' | 'East' | 'South' | 'West'

We still get a type associated with specific values, but now this gets compiled into the following:

We did not forget anything in the above block: Union types are like interfaces and do not get compiled into anything, meaning they do not increase the size of your code base or impact performance.

Also, since those types are just the union of other types (such as strings or numbers), these constants can be used as-is in a component template without needing to tweak our component class.

In other words, union types preserve type safety without degrading our app’s performance, which is a win-win.

I hope you found it useful. Thanks for reading. 🙏

Let’s get connected! You can find me on:

--

--