Enum
APIEnumeration of constant values
Motivation
Enums are useful for defining types that can only take on a limited set of values.
Define an Enum
An enum can be declared as the following example :
import { Enum } from '@w5s/core';
export const MyEnum = Enum.define({
  Foo: 'foo',
  Bar: 'bar',
});
export type MyEnum = Enum.ValueOf<typeof MyEnum>;
Matching on values
import { assertNever } from '@w5s/error';
export function getName(value: MyEnum) {
  switch (value) {
    case MyEnum.Foo:
      return 'foo_name';
    case MyEnum.Bar:
      return 'bar_name';
    default:
      assertNever(value);// Exhaustive check
  }
}
Keys & Values
To read enum keys and values, use Enum.keys and Enum.values :
export const MyEnum = Enum.define({
  Foo: 'foo',
  Bar: 'bar',
});
Enum.keys(MyEnum); // ['Foo', 'Bar']
Enum.values(MyEnum); // ['foo', 'bar']
Extending Enum
Extending an enum can be done just using the ... operator
const MyEnumValues = Enum.define({
  Foo: 'foo',
  Bar: 'bar',
});
export type MyEnum = Enum.ValueOf<typeof MyEnumValues>;
export const MyEnum = {
  ...MyEnumValues,
  someMethod(value: MyEnum | undefined) {
    switch (value) {
      case 'foo': return 'foo_label';
      case 'bar': return 'bar_label';
      default: return '';
    }
  }
}
// Enum.keys(MyEnum) will still return ['Foo', 'Bar'] !
Coding Guide
// ✓ Export a const
// ✓ PascalCase
// ✓ Singular
export const {{EnumType}} = Enum.define({
  // ✓ PascalCase
  {{EnumValueName}}: '{{EnumValue}}',
  // ...
});
// ✓ Export a type with the same name as the const
export type {{EnumType}} = Enum.ValueOf<typeof {{EnumType}}>;
FAQ
Why not using Typescript enum ?
enum ?Typescript enums have several drawbacks such as :
- 
Number based enum are not safe
enum Roles {
Admin,
}
declare function hasAccess(role: Roles): void;
hasAccess(10);// This is valid, but it should not 😣 - 
String based enum are using nominal typing (Typescript is almost full structurally typed)
enum Roles {
Admin = 'admin',
}
declare function hasAccess(role: Roles): void;
hasAccess('admin') // Invalid.
hasAccess(Roles.Admin) // Valid. 
References :
This library was created to solve these issues.