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.
What are enums 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.
Defining numeric enums
Numeric enums are the default in TypeScript. They are automatically assigned numeric values starting from 0.
enum Direction {North,South,East,West}let dir: Direction = Direction.Northconsole.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.
enum Direction {North = 0,South = 1,East = 2,West = 3}console.log(Direction.North) // Output: 0console.log(Direction.South) // Output: 1
Defining string enums
String enums are useful when the exact value of the enum members matters and you want them to be more readable.
enum Direction {North = 'NORTH',South = 'SOUTH',East = 'EAST',West = 'WEST'}console.log(Direction.North) // Output: "NORTH"
Using enums
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.
Enum usage example
Consider a simple state machine with different states represented by an enum:
enum State {Idle,Running,Stopped}let currentState: State = State.Idlefunction transitionTo(state: State) {currentState = stateconsole.log(`Transitioned to ${State[state]}`)}transitionTo(State.Running) // Output: Transitioned to Running
Enumerating object properties in TypeScript
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:
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
:
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:
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.
Iterating over enum types in TypeScript
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:
TypeScript enum definition
enum Color {Red,Green,Blue}
Iterating over enum to access names
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:
Object.keys(Color).filter((key) => isNaN(Number(key))) // Filter out numeric keys.forEach((key) => {console.log(key) // Outputs: Red, Green, Blue})
Iterating over enum to access values
To access the values (e.g., 0, 1, 2), you can directly use Object.values()
and filter by type to exclude the string keys:
Object.values(Color).filter((value) => typeof value === 'number') // Filter to keep only numeric values.forEach((value) => {console.log(value) // Outputs: 0, 1, 2})
Practical example: using enum values in a switch case
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:
const printColorName = (colorValue: Color) => {switch (colorValue) {case Color.Red:console.log('Red')breakcase Color.Green:console.log('Green')breakcase Color.Blue:console.log('Blue')breakdefault:console.log('Unknown Color')}}// Example usage:printColorName(Color.Red) // Outputs: RedprintColorName(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.
Converting enum to array
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.
1. Converting enum keys to an array
If you only need the keys, you can filter out the values, returning an array object:
enum Colors {Red,Green,Blue}const enumKeys = Object.keys(Colors).filter((key) => isNaN(Number(key)))console.log(enumKeys) // Output: ["Red", "Green", "Blue"]
2. Converting enum values to an array
To convert the enum values to an array, you can use Object.values()
with type filtering:
const enumValues = Object.values(Colors).filter((value) => typeof value === 'number')console.log(enumValues) // Output: [0, 1, 2]
3. Converting enum to array of objects (key-value pairs)
For some applications, you might need both the names and values together as objects in an array:
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.