Typescript enumerables

Kenny DuMez
Kenny DuMez
Graphite software engineer

Enumerables in TypeScript, often referred to as enums, provide a way to define a set of named constants. This makes it easier to handle and manage sets of related values in a more readable and maintainable way. This guide will explore what enums are, how to use them, and how to enumerate arrays and object properties in TypeScript.

Enums in TypeScript allow you to define a collection of related values that can be numeric or string-based. They help in making the code more expressive and are particularly useful when you have a set of fixed values for a variable.

Numeric enums are the default in TypeScript. They are automatically assigned numeric values starting from 0.

Terminal
enum Direction {
North,
South,
East,
West
}
let dir: Direction = Direction.North
console.log(dir) // Output: 0

In the example above, North is assigned the value 0, South the value 1, and so on. You can also assign specific values to the members of the enum.

Terminal
enum Direction {
North = 0,
South = 1,
East = 2,
West = 3
}
console.log(Direction.North) // Output: 0
console.log(Direction.South) // Output: 1

String enums are useful when the exact value of the enum members matters and you want them to be more readable.

Terminal
enum Direction {
North = 'NORTH',
South = 'SOUTH',
East = 'EAST',
West = 'WEST'
}
console.log(Direction.North) // Output: "NORTH"

Enums can be used in various scenarios to improve code readability and maintainability. For instance, when handling multiple states or modes, enums can make your code cleaner.

Consider a simple state machine with different states represented by an enum:

Terminal
enum State {
Idle,
Running,
Stopped
}
let currentState: State = State.Idle
function transitionTo(state: State) {
currentState = state
console.log(`Transitioned to ${State[state]}`)
}
transitionTo(State.Running) // Output: Transitioned to Running

In TypeScript, enumerating the properties of an object can be crucial for tasks such as dynamically accessing properties, manipulating data structures, or simply inspecting objects for debugging purposes. TypeScript provides several ways to enumerate or list the properties of an object.

One common approach is to use the for...in loop. This loop iterates over all enumerable properties of an object, including those inherited from the prototype chain. Here’s an example:

Terminal
const person = { name: 'Alice', age: 25 }
for (const key in person) {
console.log(key, person[key])
}

This will log "name", "Alice" and "age", 25. Note, when using for...in, it’s a good practice to check if the property belongs to the object itself and not inherited from its prototype using hasOwnProperty:

Terminal
for (const key in person) {
if (person.hasOwnProperty(key)) {
console.log(key, person[key])
}
}

Another method is Object.keys(obj), which returns an array of an object’s own enumerable property names, ignoring the prototype chain:

Terminal
const keys = Object.keys(person)
console.log(keys) // ["name", "age"]
keys.forEach((key) => console.log(key, person[key]))

Both methods are useful for different scenarios depending on whether you need to include inherited properties or just the object’s own properties.

Due to how enums are structured, iterating over enums in TypeScript involves handling both the keys and values. Here is an example that demonstrates how to iterate over enum types in TypeScript to access both the names and values, using filtering to separate numeric indices from names:

Terminal
enum Color {
Red,
Green,
Blue
}

To access the names of the enum (e.g., "Red", "Green", "Blue"), you can use Object.keys() with a filter to exclude numeric keys, which are automatically created by TypeScript for reverse mapping:

Terminal
Object.keys(Color)
.filter((key) => isNaN(Number(key))) // Filter out numeric keys
.forEach((key) => {
console.log(key) // Outputs: Red, Green, Blue
})

To access the values (e.g., 0, 1, 2), you can directly use Object.values() and filter by type to exclude the string keys:

Terminal
Object.values(Color)
.filter((value) => typeof value === 'number') // Filter to keep only numeric values
.forEach((value) => {
console.log(value) // Outputs: 0, 1, 2
})

Here’s how you might use the enum values in a functional context, like a switch case to execute code based on the enum value:

Terminal
const printColorName = (colorValue: Color) => {
switch (colorValue) {
case Color.Red:
console.log('Red')
break
case Color.Green:
console.log('Green')
break
case Color.Blue:
console.log('Blue')
break
default:
console.log('Unknown Color')
}
}
// Example usage:
printColorName(Color.Red) // Outputs: Red
printColorName(1) // Outputs: Green

This example showcases how enums can be iteratively accessed and utilized in TypeScript, providing both the keys for readable code and the values for operational logic.

Depending on if you want the enumerations' keys, values, or both, you can use different approaches to convert a group of enums into an array.

If you only need the keys, you can filter out the values, returning an array object:

Terminal
enum Colors {
Red,
Green,
Blue
}
const enumKeys = Object.keys(Colors).filter((key) => isNaN(Number(key)))
console.log(enumKeys) // Output: ["Red", "Green", "Blue"]

To convert the enum values to an array, you can use Object.values() with type filtering:

Terminal
const enumValues = Object.values(Colors).filter(
(value) => typeof value === 'number'
)
console.log(enumValues) // Output: [0, 1, 2]

For some applications, you might need both the names and values together as objects in an array:

Terminal
const enumArray = Object.keys(Colors)
.filter((key) => isNaN(Number(key))) // Ensure keys are not numeric indices
.map((key) => ({ name: key, value: Colors[key as keyof typeof Colors] }))
console.log(enumArray) // Output: [{ name: "Red", value: 0 }, { name: "Green", value: 1 }, { name: "Blue", value: 2 }]

For more information on enumerations in TypeScript, see the official documentation.

Graphite
Git stacked on GitHub

Stacked pull requests are easier to read, easier to write, and easier to manage.
Teams that stack ship better software, faster.

Or install our CLI.
Product Screenshot 1
Product Screenshot 2