You might not need TypeScript Enum
Tags: typescript, javascript, beginners, webdev
Published: 2023-09-05 14:25:58

In TypeScript, there is a feature called `Enum` which is not a type-level extension of JavaScript. Enums allow a developer to define a set of named constants.

```typescript
enum EDirection {
  Up = "Up",
  Down = "Down",
  Left = "Left",
  Right = "Right",
}

// Using the enum as a parameter
function walk(dir: EDirection) {}

walk(EDirection.Left);
```

But, on the other hand, we may not need Enum as TypeScript team says on https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums by using an object with `as const`.


```typescript
const ODirection = {
  Up: "Up",
  Down: "Down",
  Left: "Left",
  Right: "Right",
} as const;


type Direction = typeof ODirection[keyof typeof ODirection];

function run(dir: Direction) {}

run(ODirection.Right);
```

So what's the difference between Enum and Object? I'll discuss the difference in Data Types, Bundle size, and How to use aspects.
<br/>
### Data Types

#### Enum

TypeScript provides both numeric and string-based enums.

```typescript
// Numeric Enums
enum UserResponse {
  No = 0,
  Yes = 1,
}

// String Enums
enum UserResponse {
  No = "No",
  Yes = "Yes",
}
```

#### Constants

While `Constants` can cover an object with string and number property values including all data types.

```typescript
// Number
const PI = 3.14159;

// String
const GREETING = "Hello, World!";

// Boolean
const IS_ACTIVE = true;

// Array
const COLORS = ["red", "green", "blue"];

// Object
const PERSON = {
    name: "John",
    age: 30
};

// RegExp
const EMAIL_PATTERN = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;

// Null
const NO_VALUE = null;

// Undefined
const UNDEFINED_VALUE = undefined;

// Symbol
const UNIQUE_KEY = Symbol("unique");
```
<br>
<br>
### Transpiled Size

I used https://babeljs.io/repl to know the size after the code has been transpiled.

#### Enum
```typescript
enum Color {
    Red = "RED",
    Green = "GREEN",
    Blue = "BLUE"
}

// Transpiled Result
var Color = /*#__PURE__*/function (Color) {
  Color["Red"] = "RED";
  Color["Green"] = "GREEN";
  Color["Blue"] = "BLUE";
  return Color;
}(Color || {});

// Size: 153 Bytes
```

#### Constants
```typescript
const COLOR = {
    red: "RED",
    green: "GREEN",
    blue: "BLUE"
} as const;

// Transpiled Result
const COLOR = {
  red: "RED",
  green: "GREEN",
  blue: "BLUE"
};

// Size: 65 Bytes
```
<br/>

### How to use

An Enum named `EDirection` and an object named `ODirection` refer to the same thing as what we talked about earlier.

#### Enum
```typescript
walk("Left");
// This shows an error ❌
// (Argument of type '"Left"' is not assignable to parameter of type 'EDirection')

walk(EDirection.Left);
// This works well ✅
```

#### Constant

```typescript
run("Left");
// This works well ✅

run(ODirection.Left);
// This works well ✅
```

### Conclusion

Based on several aspects I've discussed earlier, we can replace Enum with Object. Object has the flexibility for defining various data types, has a smaller transpiled size, and can detect both property values or property access.

So, it's important to remember that not all cool features are the best choice. Always assess the aspects you think important. If a feature doesn't have any negative impact, then you can confidently use it.