Aller au contenu principal

Enum

Enumeration of constant values

API

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 ?

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.