Contents
If youโre looking to make your TypeScript code more organized, enums are a powerful tool. They group related values together, giving your code better structure and readability. Letโs dive in and explore how to use them!
In TypeScript, enums are declared using the enum
keyword. For example, you could create an enum to represent the different fruit prices as follows:
Example 1: Basic Enum Structure โ Key Movements
Demonstrates a common use case for enums: making choices within a limited set clearer.
enum Movement {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT"
}
function handlePlayerInput(key: string) {
switch (key) {
case Movement.Up:
// Move player character up
break;
case Movement.Down:
// Move player character down
break;
// ... other cases
}
}
This demonstrates the fundamental syntax for defining an enum. The Movement
enum has four members representing directions.
Example 2: Enums with Values
Enums can have associated values (numbers, strings, etc.). Here, StatusCode
associates HTTP status codes, ensuring type-safety and preventing the use of arbitrary numbers.
enum StatusCode {
OK = 200,
BadRequest = 400,
NotFound = 404
}
function handleResponse(code: StatusCode) {
if (code === StatusCode.OK) {
// Handle successful response
} else if (code === StatusCode.NotFound) {
// Handle resource not found
}
// ... other cases
}
Image source: https://restfulapi.net/http-status-codes
Example 3: Enum from Redux Toolkit
Redux Toolkit is a popular library for state management in React applications. It makes heavy use of TypeScript for type safety.
This enum defines distinct states for asynchronous actions (like fetching data). This is common in state management libraries.
enum PayloadActionLoadingState {
Idle = "idle",
Loading = "loading",
Failed = "failed",
Success = "success"
}
Example 4: Enum as a Discriminated Union
This enum defines two possible shapes: Circle
and Rectangle
. It acts as a foundation for ensuring type safety when working with different shapes.
Each shape type (Circle
, Rectangle
) is represented as a member of the ShapeType
enum.
The Shape
interface has a type
property that must be a member of the ShapeType
enum.
enum ShapeType {
Circle = "Circle",
Rectangle = "Rectangle"
}
interface Shape {
type: ShapeType;
}
interface Circle extends Shape {
type: ShapeType.Circle;
radius: number;
}
interface Rectangle extends Shape {
type: ShapeType.Rectangle;
width: number;
height: number;
}
function calculateArea(shape: Shape): number {
switch (shape.type) {
case ShapeType.Circle:
const circle = shape as Circle; // Type assertion to Circle
return Math.PI * circle.radius * circle.radius;
case ShapeType.Rectangle:
const rectangle = shape as Rectangle; // Type assertion to Rectangle
return rectangle.width * rectangle.height;
default:
throw new Error("Invalid shape type");
}
}
Specific shape interfaces (Circle
, Rectangle
) extend the base Shape
interface and must have their type
property set to the corresponding enum value.
This lets the calculateArea
function use the type
property as a discriminator to determine the appropriate calculation.
Example 5: Enums as Data Structures
This TypeScript code defines a simple model for representing playing cards, focusing on the suits, ranks, and the color of the card, which is derived from its suit.
It consists of two enums, a function to get a cardโs numerical value, an interface to describe a cardโs structure, and a function to create a card.
enum Suit {
Hearts = "♥", // Red suit
Diamonds = "♦", // Red suit
Clubs = "♣", // Black suit
Spades = "♠" // Black suit
}
enum Rank {
Ace = 1,
Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten,
Jack, Queen, King
}
function getCardValue(rank: Rank): number {
if (rank <= Rank.Ten) {
return rank;
} else {
return 10;
}
}
interface Card {
suit: Suit;
rank: Rank;
color: string; // Derived property based on suit
}
function createCard(suit: Suit, rank: Rank): Card {
return {
suit,
rank,
color: suit === Suit.Hearts || suit === Suit.Diamonds ? 'Red' : 'Black'
}
}
// Usage
let card1 = createCard(Suit.Hearts, Rank.Ace);
console.log(`The Ace of Hearts is red: ${card1.color}`); // Output: The Ace of Hearts is red: Red
let card2 = createCard(Suit.Spades, Rank.Queen);
console.log(`The Queen of Spades is black: ${card2.color}`); // Output: The Queen of Spades is black: Black
Function getCardValue
takes a Rank
as an argument and returns a number. For ranks Ace
through Ten
(numerically 1 to 10), it returns the rank’s numeric value. For face cards (Jack
, Queen
, King
), which have rank values greater than 10, it returns 10.
Two card objects are created using the createCard
function: card1
as the Ace of Hearts (which is red) and card2
as the Queen of Spades (which is black).
This code is a straightforward way to model the basic properties of playing cards in a type-safe manner using TypeScriptโs features like enums, interfaces, and type inference.
Conclusion
Enums provide a solid foundation for clean and structured TypeScript code. As your projects grow in complexity, their benefits will continue to shine.
TypeScript enums are a powerful tool to elevate your code. They enhance readability, maintainability, and type safety.
This article was originally posted on Medium.
[fluentform id="8"]