Typescript Enums And Literal Types Complete Guide

 Last Update:2025-06-22T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    9 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of TypeScript Enums and Literal Types

TypeScript Enums and Literal Types: A Comprehensive Guide

Enumerations (Enums)

Enums in TypeScript are a feature that allows you to define a set of named constants. Enums are useful for providing readable names to sets of numeric values or string values. Enums help in making your code more organized, and maintainable by reducing the risk of errors.

Numeric Enums:

By default, the enum members in TypeScript are given numeric values starting at 0 and incrementing in one step. However, you can change the default behavior by explicitly setting the value for each member.

enum Direction {
  Up,       // 0
  Down,     // 1
  Left,     // 2
  Right     // 3
}

const currentDirection: Direction = Direction.Left;
console.log(currentDirection); // Prints: 2

You can also assign specific values to each member:

enum Direction {
  Up = 1,
  Down,
  Left = 10,
  Right
}

console.log(Direction.Right); // Prints: 11

String Enums:

Using string values for enum members increases the readability and maintainability of your code since the enum member names will appear in the generated JavaScript.

enum Directions {
  Up = 'UP',
  Down = 'DOWN',
  Left = 'LEFT',
  Right = 'RIGHT'
}

console.log(Directions.Up); // Prints: 'UP'

Reverse Mappings:

In numeric enums, TypeScript generates a reverse mapping, which allows you to lookup the names of the enum members from their values.

let directionName: string = Direction[2];
console.log(directionName); // Prints: 'Left'

Const Enums:

When you use the const keyword, the compiler generates more efficient code since it removes the enum definition and replaces all usages with the inline values. This helps in reducing the size of the generated code.

const enum Colors {
  Red,
  Green,
  Blue
}

const color: number = Colors.Green;

In the above example, the generated JavaScript won't define a Colors object. Instead, it will replace Colors.Green with 1 directly.

Literal Types

Literal Types restrict a variable to be a certain value(s). They are often used in conjunction with Union Types to define a set of values that a variable can hold. Literal types are useful for defining constants and enhancing the accuracy of types.

String Literal Types:

You can define a variable that can hold a specific set of string values.

type DirectionLiteral = 'up' | 'down' | 'left' | 'right';

const direction: DirectionLiteral = 'up';

Numeric Literal Types:

Similar to string literals, you can also define numeric literals.

type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;

const diceRoll: DiceRoll = 4;

Boolean Literal Types:

Using boolean literal types, you can make a variable hold only true or false.

type TrueOrFalse = true | false;

const isCorrect: TrueOrFalse = true;

Combining Literals with Other Types:

You can mix literal types with other types to create more expressive types.

type MessageId = 'success' | 'error' | 'warning';

interface UserMessage {
  messageId: MessageId;
  message: string;
}

const successMessage: UserMessage = {
  messageId: 'success',
  message: 'Action completed successfully'
};

Practical Use Cases

  • Configuration Values: Defining enums for configuration constants makes the code more readable and self-documenting.

  • Action Types in Redux: Enums can be used to define action types in Redux, making it less error-prone to dispatch actions.

  • Error Codes: Defining error codes as enums can make it easier to handle different types of errors in a program.

  • Literal Types for Constants: Using literal types for constants ensures that the variable cannot accidentally hold an invalid value.

Conclusion

TypeScript's enums and literal types offer developers a powerful way to ensure the type safety and clarity of their code. By using enums to define named constants and literal types to restrict the values a variable can hold, you can build more robust applications while reducing the likelihood of errors due to invalid data types.

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement TypeScript Enums and Literal Types

Complete Examples, Step by Step for Beginners: TypeScript Enums and Literal Types


Understanding Enums in TypeScript

Enums (short for enumerations) are a way to define a set of named constants that can be used throughout your codebase. This feature helps in making your code more readable and maintainable.

Step 1: Defining a Simple Enum

Let's create an enum called Direction that will contain values for the four cardinal directions.

enum Direction {
    North,
    East,
    South,
    West
}

console.log(Direction.North); // Output: 0
console.log(Direction.East);  // Output: 1
console.log(Direction.South); // Output: 2
console.log(Direction.West);  // Output: 3

By default, TypeScript assigns numeric values to the enum members, starting from 0.

Step 2: Setting Numeric Values for Enum Members

We can also assign specific numeric values to each member of the enum:

enum Direction {
    North = 1,
    East = 2,
    South = 3,
    West = 4
}

console.log(Direction.North); // Output: 1
console.log(Direction.East);  // Output: 2
console.log(Direction.South); // Output: 3
console.log(Direction.West);  // Output: 4

Step 3: Using String Enums

In addition to numeric enums, TypeScript also supports string enums where each value is a string literal:

enum Direction {
    North = "NORTH",
    East = "EAST",
    South = "SOUTH",
    West = "WEST"
}

console.log(Direction.North); // Output: "NORTH"
console.log(Direction.East);  // Output: "EAST"
console.log(Direction.South); // Output: "SOUTH"
console.log(Direction.West);  // Output: "WEST"

Step 4: Getting Keys from Enums

Sometimes, you may need to get all the keys from an enum:

const directions = Object.keys(Direction);
console.log(directions); 
// Output: [ 'North', 'East', 'South', 'West' ] for numeric enum
// Output: ['North', 'East', 'South', 'West'] for string enum

// For numeric enums, Object.values() might include the keys and values:
const directionValues = Object.values(Direction);
console.log(directionValues); 
// Output: ["North", 0, "East", 1, "South", 2, "West", 3] for numeric enum
// Output: [ 'NORTH', 'EAST', 'SOUTH', 'WEST' ] for string enum

Step 5: Using Enums as Parameters

Here’s how to use an enum as a parameter in a function:

enum Action {
    Submit,
    Cancel,
    Reset
}

function handleAction(action: Action): string {
    switch(action) {
        case Action.Submit: return "Action Submitted!";
        case Action.Cancel: return "Action Cancelled!";
        case Action.Reset: return "Action Reset!";
        default: return "Unknown action!";
    }
}

console.log(handleAction(Action.Submit)); // Output: "Action Submitted!"

Understanding Literal Types in TypeScript

Literal types allow you to specify that a variable or function parameter must have a very specific, hardcoded value. They are useful to make your code more explicit.

Step 1: Defining String Literal Types

String literal types ensure that the variable can only hold specific string values.

type DirectionLiteral = 'north' | 'east' | 'south' | 'west';

function moveTo(direction: DirectionLiteral): void {
    console.log(`Moving to ${direction}`);
}

moveTo('north');  // Correct
moveTo('up');     // Error: Argument of type '"up"' is not assignable to parameter of type 'DirectionLiteral'

Step 2: Defining Numeric Literal Types

Numeric literal types are similar to string literal types but they allow numeric values instead.

type PossibleScores = 0 | 5 | 10 | 15;

function awardScore(points: PossibleScores): void {
    console.log(`Awarding ${points} points`);
}

awardScore(5);

awardScore(3);  // Error: Argument of type '3' is not assignable to parameter of type 'PossibleScores'

Step 3: Combining Enums with Literal Types

You can combine enums with literal types to make sure that a variable or parameter holds one of the values from the enum:

enum Color {
    Red,
    Green,
    Blue
}

type ColorLiteral = "Red" | "Green" | "Blue";

function paint(color: ColorLiteral): void {
    console.log(`Painting in color ${color}`);
}

paint(Color.Red.toString());  // Correct, converting enum value to string first
paint("Red");                 // Correct
paint("Yellow");              // Error: Argument of type '"Yellow"' is not assignable to parameter of type 'ColorLiteral'

Step 4: Using Literal Types for Function Return Values

You can also restrict the allowed return values of a function using literal types.

type YesOrNo = 'Yes' | 'No';

function willAttend(event: string): YesOrNo {
    if (event === 'wedding') {
        return 'Yes';
    } else {
        return 'No';
    }
}

console.log(willAttend('wedding'));  // Output: 'Yes'
console.log(willAttend('meeting'));  // Output: 'No'
console.log(willAttend('concert'));  // No error (returns 'Yes' or 'No')

Practical Exercise: Building a Game Control System

Now, let’s use enums and literal types together to build a simple game control system.

Define Enums for Movement and Actions

enum Movement {
    MoveLeft = 'MOVE_LEFT',
    MoveRight = 'MOVE_RIGHT',
    MoveForward = 'MOVE_FORWARD',
    MoveBackward = 'MOVE_BACKWARD'
}

enum Action {
    Shoot = 'SHOOT',
    Jump = 'JUMP',
    Duck = 'DUCK',
    Crouch = 'CROUCH'
}

Create a Type that Combines Movement and Action

type ControlCommand = Movement.Shoot | Movement.Jump | Movement.Duck | Movement.Crouch 
                   | Action.MoveLeft | Action.MoveRight | Action.MoveForward | Action.MoveBackward;

Define the performCommand Function

This function will execute a given command if it matches any of the enum values combined.

function performCommand(command: ControlCommand): string {
    switch(command) {
        case Movement.MoveLeft: 
            return "Moving left...";
        case Movement.MoveRight: 
            return "Moving right...";
        case Movement.MoveForward: 
            return "Moving forward...";
        case Movement.MoveBackward: 
            return "Moving backward...";
        case Action.Shoot: 
            return "Shooting!";
        case Action.Jump: 
            return "Jumping!";
        case Action.Duck: 
            return "Ducking!";
        case Action.Crouch: 
            return "Crouching!";
        default: 
            return "Unknown command!" // This line won't be triggered due to ControlCommand type restriction
    }
}

Testing the System

Top 10 Interview Questions & Answers on TypeScript Enums and Literal Types

1. What are Enums in TypeScript?

Answer: Enums (short for enumerations) in TypeScript are a way to define a set of named constants. They allow you to define a set of related values and refer to them by a name instead of using magic numbers or strings. This improves code readability and maintainability.

Example:

enum Day {
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
}

2. How can you start an Enum with a different number other than 0?

Answer: By default, the first value of an Enum starts with 0. You can start it at a different number by initializing the first member with a specific value.

Example:

enum Day {
    Sunday = 1,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
}

Here, Day.Sunday will be 1, Day.Monday will be 2, and so on.

3. What are String Enums in TypeScript?

Answer: String Enums in TypeScript allow you to assign string values to members instead of the default numeric ones. This can make debugging and serialization easier.

Example:

enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT"
}

4. What are Literal Types in TypeScript?

Answer: Literal Types in TypeScript refer to the type of specific values. They are particularly useful when combined with unions to create fixed sets of values.

Example:

type Direction = "north" | "south" | "east" | "west";
let myDirection: Direction = "north";
// myDirection can only be one of the four values specified

5. How can Enums and Literal Types be used together?

Answer: Enums and Literal Types can sometimes serve similar purposes, but they are used in different contexts. Enums are often used when you have a predefined set of constants, usually numbers or strings. Literal Types are used when you want to restrict a variable to a small set of specific values, especially when these values are known at compile time and are strings or numbers.

Example:

enum Status {
    Active = "active",
    Inactive = "inactive",
    Pending = "pending"
}

type Action = {
    type: "activate" | "deactivate" | "pending";
}

function handleAction(action: Action) {
    // Implementation based on the action type
}

6. Why use Enums over Literal Types?

Answer: Enums provide a way to group related constants and use them like a namespace, which can make the code more organized. They also offer better tooling support, such as auto-completion in editors.

Literal Types are more flexible when used with unions, as they allow defining a variable that can only take one of the specified values. They can also be used for more complex type definitions not easily represented with enums.

7. How can you use Enums as a type?

Answer: Enums in TypeScript not only define a set of values but also define a type that can be used in type annotations.

Example:

enum Color {
    Red,
    Green,
    Blue
}

function printColor(color: Color) {
    console.log(color);
}

printColor(Color.Red); // Valid
printColor(0);        // Valid, as it maps to Color.Red
printColor(99);       // Compile error, as it does not have a mapping in Color

8. What are Reverse Mappings in TypeScript Enums?

Answer: Reverse mappings in TypeScript Enums allow you to access the Enum values by their numeric values, not just by their names. This can be useful for debugging or when you have a numeric value and want to find out its Enum name.

Example:

enum Color {
    Red = 1,
    Green,
    Blue,
}

console.log(Color.Red);   // Outputs: 1
console.log(Color[1]);    // Outputs: "Red"

9. Can you have const Enums in TypeScript?

Answer: Yes, you can have const enums in TypeScript. Unlike regular enums, const enums do not generate any JavaScript code for the enum itself; instead, the compiler will inline the enum's values at compile time. This can result in smaller and more performant code.

Example:

const enum Color {
    Red,
    Green,
    Blue,
}

let myColor = Color.Red; // Will be compiled to 'let myColor = 0;'

10. What are some use cases for Literal Types and Enums?

Answer:

  • Enums:

    • Defining a set of fixed constants that represent a concept (e.g., days of the week).
    • Mapping HTTP status codes.
    • Creating a set of configuration options.
  • Literal Types:

    • Restricting function parameters to specific values (useful for API calls, states, etc.).
    • Creating type-safe configurations.
    • Defining action types for use in reducers in state management libraries like Redux.

You May Like This Related .NET Topic

Login to post a comment.