Enum

Il y a deux problèmes majeurs avec la notation enum typescript.

Les enums numériques ne vous protègent pas.

enum Direction {
  UP,
  DOWN,
  LEFT,
  RIGHT,
}

declare function move(direction: Direction): void;

move(42); // pas de bug ...

Les enums textuels ne permettent pas d'affecter une primitive dont la valeur est identique. C'est assez emmerdant car cela vous force a caster manuellement des données. Le cast manuel, c'est (en général) une mauvaise pratique.

enum Direction {
  UP = "up",
  DOWN = "down",
  LEFT = "left",
  RIGHT = "right"
}

declare function move(direction: Direction): void;

move("up"); // bug

Une alternative est d'utiliser un objet literal.

export const SOMETHING_TYPE = {
    A: 0,
    B: "b"
} as const; // use exact value as type, not the primitive
export type SomethingType = typeof SOMETHING_TYPE[keyof typeof SOMETHING_TYPE];

const test1: SomethingType = 0; // pas de bug
const test2: SomethingType = "b"; // pas de bug
const test3: SomethingType = 42; // BUG
const test4: SomethingType = "error"; // BUG

function isSomething(value: unknown): value is SomethingType {
    return Object.values(SOMETHING_TYPE).includes(value as SomethingType)
}
isSomething(0); // true
isSomething(42); // false

[...]

if (isSomething(foobar)) {
    // foobar a désormais le type "SomethingType"
}

Ainsi vous garantissez non seulement le type, mais vous vous autorisez également à affecter des primitives et à verifier le type d'une variable.