7 TypeScript Tricks with Enum (and Fruits) 🧺

Relying on basic enums, (numeric and auto-incremented) is standard and the most common use case. Yet Enums can offer much more:

In the rest of this post, let's assume the following code is available:

enum Fruit {
  APPLE = '🍎',
  BANANA = '🍌',
  CHERRY = 'πŸ’',
}

1. Merge enums

Merging enums is pretty straightforward using the pipe | operator:

enum OtherFruit {
  DATE = 'date',
}

type AnyFruit = Fruit | OtherFruit

2. Enum subsets

Because cherries may not be as tasty as other fruits, let's exclude them:

type YummyFruits = Exclude<Fruit, Fruit.CHERRY>
// => type YummyFruits = Fruit.APPLE | Fruit.BANANA

3. Get the keys of an enum dynamically

This one needs the use of two type operators: keyof and typeof.

type FruitKey = keyof typeof Fruit
// => type FruitKey = "APPLE" | "BANANA" | "CHERRY"

const keys = Object.keys(Fruit) as FruitKey[]
// => ["APPLE", "BANANA", "CHERRY"]

4. Get the values of an enum dynamically

This snippet leverages the Template Literal type operator:

type FruitValue = `${Fruit}`
// => type FruitValue = "🍎" | "🍌" | "πŸ’"

const values: FruitValue[] = Object.values(Fruit)
// => ["🍎", "🍌", "πŸ’"]

5. Iterate over an enum keys

Looping through the enum keys is as simple as:

for (let fruit of Object.keys(Fruit)) {
  console.log(fruit)
}
// => APPLE
//    BANANA
//    CHERRY

6. Iterate over an enum values

In the same spirit, looping through the enum values:

for (let fruit of Object.values(Fruit)) {
  console.log(fruit)
}
// => 🍎
//    🍌
//    πŸ’

7. const enum

By default, enums generate a bunch of code when compiled to JavaScript:

var Fruit;
(function (Fruit) {
    Fruit["APPLE"] = "🍎";
    Fruit["BANANA"] = "🍌";
    Fruit["CHERRY"] = "πŸ’";
})(Fruit || (Fruit = {}));

There is however a way not to generate this much code: by leveraging const enum.

Adding just a const in front of our Fruit enum makes a big difference:

const enum Fruit {
  APPLE = '🍎',
  BANANA = '🍌',
  CHERRY = 'πŸ’',
}

...as it compiles to nothing. πŸ•³οΈ

Just until we use part of its values:

const chosenFruit = Fruit.BANANA
// => compiles to:
// var chosenFruit = "🍌";

33