---
title: "Why I always use ‘enum’ in JS"
description: "I wrote this post under the influence of the article “WHY I DON’T USE ENUMS IN TYPESCRIPT, AND NEITHER SHOULD YOU” (now deleted). In short, the author suggested using objects inste"
date: 2024-05-23
---

I wrote this post under the influence of the article “WHY I DON’T USE
ENUMS IN TYPESCRIPT, AND NEITHER SHOULD YOU” (now deleted). In short,
the author suggested using `objects` instead of `enums` in TS.

<figure>
<img src="/medium/img/2feb64992e54/image-01.png" alt="Image 2" />
</figure>

That is, instead of:

``` ts
enum Colors {
  BLUE = 'blue',
  GREEN = 'green',
  RED = 'red',
}
function printColor(color: Colors) { console.log(color); }
printColor(Colors.BLUE);
printColor('blue');
```

it was proposed to use something like:

``` ts
const Colors = {
  BLUE: 'blue',
  GREEN: 'green',
  RED: 'red',
} as const;
type Colors = typeof Colors[keyof typeof Colors];
function printColor(color: Colors) { console.log(color); }
printColor(Colors.BLUE);
printColor('blue');
```

The author cited the ability to use literals (`blue`) instead of
importing the source file with the enum and using its values as an
advantage of this approach.

I have an article “[So, What Is the Ultimate Goal of
Programming?](https://flancer32.com/so-what-is-the-ultimate-goal-of-programming-0fd5def59fdc)”
in which I examine the sequence of programming goals in a hierarchy
similar to Maslow’s pyramid:

<figure>
<img src="/medium/img/2feb64992e54/image-02.png" alt="Image 3" />
</figure>

The goals

And I dare to claim that the approach with literals instead of enums
corresponds to the first level of goals — convenience of writing code,
but does not correspond to the highest level of goals I have seen — The
Modifying.

Indeed, a string literal is much more convenient for writing code.

``` js
invoice.setState('pending');
order.setState('pending');
```

But a search for the `pending` state of an order now collides with
similar invoice states. This is the trade-off for avoiding imports and
literals.

In [my JS
code](https://github.com/teqfw/core/blob/1af0e85783e95fbbbdee82a8b116eb17e9bc34a5/src/Shared/Enum/Sphere.mjs),
I use namespaces taken from Zend1

``` js
const TeqFw_Core_Shared_Enum_Sphere = {
  BACK: 'BACK',
  FRONT: 'FRONT',
  SHARED: 'SHARED',
};
Object.freeze(TeqFw_Core_Shared_Enum_Sphere);
export default TeqFw_Core_Shared_Enum_Sphere;
```

and during the call, I use [dependency
injection](https://github.com/teqfw/web/blob/441d166c8cea10cbc70f649bcca6df008c24c431/src/Back/App/Server/Handler/Config/A/Di.mjs#L30)
and
[JSDocs](https://github.com/teqfw/web/blob/441d166c8cea10cbc70f649bcca6df008c24c431/src/Back/App/Server/Handler/Config/A/Di.mjs#L21).

``` js
export default function ({TeqFw_Core_Shared_Enum_Sphere$: SPHERE}) {
  if (one.sphere === SPHERE.FRONT || one.sphere === SPHERE.SHARED) {
    // ...
  }
}
```

This lets us find every use of `TeqFw_Core_Shared_Enum_Sphere` with a
text search. JSDoc also helps the IDE navigate to each enum value.

Yes, unlike TS, such an approach does not prohibit the use of literals
directly when calling code:

``` js
if (one.sphere === 'FRONT' || one.sphere === 'SHARED') {
  // ...
}
```

However, it is your responsibility as a programmer to use the
capabilities of the available tools for good and not for evil.

Yes, I understand that `enum` is not actually implemented in JS
(although the word itself is reserved), but I believe that you can write
code as if it were there even without it :)
