DEV Community

Discussion on: Typescript Enums are bad!!1!!!1!!one - Are they really?

Collapse
 
dscheglov profile image
Dmitry Scheglov

Well, we met the problems with enums when we started using automatic type generation from GraphQL-schema.

The server application types are defined separately from the auto-generated types to allow TS to perform typecheking in the GQL-resolvers.

We need it to be sure that we don't return an unexpected (undeclared) error code to clients and we correctly interpret the GQL-parameters received from the clients.

Two enums separaterly declared couldn't be substituted one with another even if they have the same list of pairs name -> value.

enum EFFECT1_FAILURE_CODE {
  ERROR_1 = 'EEFF_ERROR_1',
  ERROR_2 = 'EEFF_ERROR_2'
}

enum EFFECT2_FAILURE_CODE {
  ERROR_1 = 'EEFF_ERROR_1',
  ERROR_2 = 'EEFF_ERROR_2',
}

declare function f(failure: EFFECT1_FAILURE_CODE): void;

function g(failure: EFFECT2_FAILURE_CODE) {
  f(failure);
  // Argument of type 'EFFECT2_FAILURE_CODE' is not
  // assignable to parameter of type 'EFFECT1_FAILURE_CODE'
}
Enter fullscreen mode Exit fullscreen mode

So, on the application level we had to refactor our enums to the UNIONS. And we re-configured typegeneration to emit the unions for GQL enums. And that's it -- everything works.

const EFFECT1_FAILURE_CODE = {
  ERROR_1: 'EEFF_ERROR_1' as const,
  ERROR_2: 'EEFF_ERROR_2' as const,
}

type EFFECT1_FAILURE_CODE = typeof EFFECT1_FAILURE_CODE[keyof typeof EFFECT1_FAILURE_CODE];

const EFFECT2_FAILURE_CODE = {
  ERROR_1: 'EEFF_ERROR_1' as const,
  ERROR_2: 'EEFF_ERROR_2' as const,
}

type EFFECT2_FAILURE_CODE = typeof EFFECT2_FAILURE_CODE[keyof typeof EFFECT2_FAILURE_CODE];

declare function f(failure: EFFECT1_FAILURE_CODE): void;

function g(failure: EFFECT2_FAILURE_CODE) {
  f(failure); // Ok!
}
Enter fullscreen mode Exit fullscreen mode

So. NO ENUMS any more!

Collapse
 
dvddpl profile image
Davide de Paolis

nice real life example !