ts-enum-util
Strictly typed utilities for working with TypeScript enums (and string/number literal union types).
NOTE: Be sure to read about supported TypeScript versions in the Requirements section.
Contents
What is it?
ts-enum-util
provides type-safe utilities to improve the usefulness of TypeScript enums.
There are two major and distinct aspects to ts-enum-util
.
Enum Wrapper Utilities
A wrapper around an enum, or "enum-like object", that provides a variety of type-safe
utilities in terms of the run-time representation fo the enum's keys/values. Some
examples include:
- Get a list of an enum's keys, values, or key/value pairs.
- Look up values by key with run-time key validation and optional result defaulting.
- Reverse lookup of keys by value (for string enums too!) with run-time value validation and optional result defaulting.
- Run-time validation that a specified value or key is valid for a given enum, with compile-time type guards.
- Treat an enum similar to an Array of key/value tuples.
- Treat an enum similar to a Map of values.
All of these utilities are very specifically typed for each enum via generics and type inference.
Enum Value Visitor/Mapper
A visitor pattern for processing a single value whose type is an enum, or union of
string/number literals. It's like a switch statement that forces you to implement
every possible case (including null
or undefined
, if relevant), avoiding bugs
because you forgot to handle one of the enum's values, or because the enum
definition was updated with a new value and you forgot to update existing code to
handle the new value.
The more generalized "visit" functionallity has you associate a different function
with each possible value of an enum or string/number literal union.
The appropriate function is executed (and its return value returned) based on
which value the argument is at run-time.
A streamlined "map" functionality has you simply associate values (of any type)
with each possible value of an enum or string/number literal union.
The appropriate mapped value is returned based on which value the argument is at run-time.
Installation
Install via NPM:
npm i -s ts-enum-util
Getting Started
Import $enum
:
import { $enum } from "ts-enum-util";
Define an enum
:
enum Color {
R,
G,
B
}
Use $enum()
as a function to access Enum Wrapper Utilities for your enum
:
const values = $enum(Color).getValues();
Use $enum.visitValue()
or $enum.mapValue()
to access Enum Value Visitor/Mapper functionality:
function doColorAction(color: Color): void {
$enum.visitValue(color).with({
[Color.R]: () => {
window.alert("Red Alert!");
},
[Color.G]: () => {
window.location = "http://google.com";
},
[Color.B]: () => {
console.log("Blue");
}
});
}
function getColorLabel(color: Color | undefined): string {
return $enum.mapValue(color).with({
[Color.R]: "Red",
[Color.G]: "Green",
[Color.B]: "Blue",
[$enum.handleUndefined]: "Unspecified"
});
}
Usage Documentation/Examples
To keep the size of the README under control, usage documentation and examples have
been split out to separate files:
Requirements
- TypeScript 2.9+:
ts-enum-util
is all about strictly type-safe utilities
around TypeScript enums, so it would be much less useful in a plain JavaScript
project. More specifically, TypeScript 2.9 included advancements in handling
number literals as property names of object types, which is necessary for
implementing some ts-enum-util
functionality consistently for both string and
number enum types.
- Stuck with an older version of TypeScript?
- For Value Visitor/Mapper functionality, check out
ts-string-visitor
(npm,
github). NOTE:
numeric value visiting/mapping not supported! - For Enum Wrapper
functionality, check out v3 or v2 of
ts-enum-util
.
- ES6 Features: The following ES6 features are used by
ts-enum-util
, so they
must exist (either natively or via polyfill) in the run-time environment:
WeakMap
Symbol
Symbol.iterator
Symbol.toStringTag
Why is the main export named $enum
?
I wanted something short, simple, and easy to remember that was unlikely to conflict with anything else so that no one would have to alias it when importing it. By exporting a clear, memorable, and uniquely named "thing", this allows you to simply start writing code that uses $enum
and most IDEs can take care of inserting the import { $enum } from "ts-enum-util"; for you (either automatically, or with a quick keyboard shortcut).
I ended up using inspiration from the naming of jquery's $()
function. Many javascript developers are familiar with jquery, and the fact that $()
gives you a wrapper around a raw DOM element to expose additional/simplified functionality around the DOM element.
Similarly, $enum()
gives you a wrapper around a raw enum to expose additional/simplified functionality around the enum.