Publication date:

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.

Image 2

That is, instead of:

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:

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?” in which I examine the sequence of programming goals in a hierarchy similar to Maslow’s pyramid:

Image 3

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.

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, I use namespaces taken from Zend1

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 and JSDocs.

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:

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 :)