Introduction

Welcome to our next lesson in our TypeScript data structures revision course! Today, we will delve deeply into TypeScript Maps. Much like a bookshelf, Maps allow you to quickly select the book (value) you desire by reading its label (key). They are vital to TypeScript for quickly accessing values using keys, with the added benefit of type safety for efficient key insertion and deletion. So, let's explore TypeScript Maps for a clearer understanding of these concepts and leverage TypeScript's type-checking capabilities.

TypeScript Maps

Our journey starts with TypeScript Maps, a pivotal data structure that holds data as key-value pairs. Imagine storing your friend's contact info in such a way that allows you to search for your friend's name (the key) and instantly find their phone number (the value). To begin working with TypeScript Maps, you initiate an empty Map using the new Map<>() constructor with type annotations to specify the types of keys and values the Map will hold. The first type in the annotation represents the key type, and the second type represents the value type.

class PhoneBook {
    private contacts: Map<string, string>;

    constructor() {
        // An empty Map with type annotations
        this.contacts = new Map<string, string>();
    }

    addContact(name: string, phoneNumber: string): void {
        // Method to add a contact
        this.contacts.set(name, phoneNumber);
    }

    getPhoneNumber(name: string): string | undefined {
        // Method to retrieve contact's phone number, or undefined if it's not in contacts
        return this.contacts.get(name);
    }
}

// Create a PhoneBook instance
const phoneBook = new PhoneBook();

// Add contacts
phoneBook.addContact("Alice", "123-456-7890");
phoneBook.addContact("Bob", "234-567-8901");
console.log(phoneBook.getPhoneNumber("Alice")); // Output: "123-456-7890"
console.log(phoneBook.getPhoneNumber("Bobby")); // Output: undefined

In the above code, we create a PhoneBook class that uses a Map to store contacts. As you can see, Maps in TypeScript simplify the processes of adding, modifying, and accessing information with unique keys, all while maintaining type safety. The specific operations involved in utilizing these features will be discussed in the next section.

Operations in Maps

TypeScript Maps enable a variety of operations for manipulating data, such as setting, getting, deleting key-value pairs, and more. Understanding these operations is crucial for efficient data handling in TypeScript, and type annotations further enhance safety and clarity.

  • Add or Update Entries: Use the set method to add a new key-value pair or update an existing key with a new value. This allows dynamic modifications without a predefined structure.

  • Retrieve Values: The get method retrieves the value associated with a given key. It returns undefined if the key is not present.

  • Check Key Existence: The has method checks whether a specific key exists in the Map, returning true if it does and false otherwise.

  • Delete Entries: Utilize the delete method to remove a key-value pair from the Map, aiding in active management of its contents. If the key does not exist, the Map remains unchanged and no error occurs, allowing for safe management of its contents.

  • Determine Map Size: The size property provides the total number of key-value pairs currently in the Map.

Let's see how these operations work in the context of a TaskManager class:

class TaskManager {
    private tasks: Map<string, string>;

    constructor() {
        // Initialize with an empty Map
        this.tasks = new Map<string, string>();
    }

    addUpdateTask(taskName: string, status: string): void {
        // Add a new task or update an existing task
        this.tasks.set(taskName, status);
    }

    getTaskStatus(taskName: string): string {
        // Retrieve the status of a task; Returns "Not Found" if the task does not exist
        return this.tasks.get(taskName) || "Not Found";
    }

    deleteTask(taskName: string): void {
        // Removes a task using its name
        if (this.tasks.has(taskName)) {
            this.tasks.delete(taskName);
        } else {
            console.log(`Task '${taskName}' not found.`);
        }
    }

    getTaskCount(): number {
        // Returns the number of tasks in the TaskManager
        return this.tasks.size;
    }
}

// Test the TaskManager class
const myTasks = new TaskManager();
myTasks.addUpdateTask("Buy Milk", "Pending");
console.log(myTasks.getTaskStatus("Buy Milk"));  // Output: Pending
myTasks.addUpdateTask("Buy Milk", "Completed");
console.log(myTasks.getTaskStatus("Buy Milk"));  // Output: Completed

myTasks.deleteTask("Buy Milk");
console.log(myTasks.getTaskStatus("Buy Milk"));  // Output: Not Found

myTasks.addUpdateTask("Clean House", "In Progress");
console.log(myTasks.getTaskCount());  // Output: 1

This example showcases how to leverage Map operations in TypeScript to effectively manage data by adding, updating, retrieving, deleting entries, and checking the number of entries through a simulated Task Manager application.

Looping Through Maps
Nesting with Maps
Hands-on Example
Lesson Summary and Practice

Well done! Today, we delved into TypeScript Maps and explored various operations, emphasizing the importance of type safety and TypeScript-specific features. We now invite you to get hands-on experience with the upcoming practice exercises. Mastering these concepts and honing your TypeScript Map skills require regular practice. Happy learning!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal