A Comprehensive Guide to Maps in TypeScript: Going Beyond Plain Objects

@rnab
3 min readNov 5, 2024

--

When developing JavaScript or TypeScript applications, you might often need a structure to store key-value pairs. While plain objects have traditionally been the go-to for this purpose, they come with limitations regarding the types of keys allowed and potential pitfalls around inherited properties and prototype chains.

Fortunately, there’s a more robust alternative: Map. In this guide, we'll take an in-depth look at how to use the Map object in TypeScript, exploring its functionality through comprehensive code examples.

What is a Map?

A Map is an ordered collection of key-value pairs that provides several advantages over regular objects:

  1. The keys can be of any type (including functions, objects, and primitive values).
  2. It preserves the order of elements.
  3. It comes with built-in methods tailored for managing data efficiently.
  4. There are no surprises from the prototype chain affecting the stored entries.

Creating a Map

To create a map in TypeScript, you simply instantiate it using the Map constructor:

let myMap = new Map<string, number>(); // This map will have string keys and number values

You can also initialize a map with multiple key-value pairs:

const initialData = [
["apple", 10],
["banana", 5]
];
let fruitMap = new Map<string, number>(initialData);

Basic Operations

Adding Entries

Use the set method to add key-value pairs:

fruitMap.set("orange", 15);
console.log(fruitMap); // Map { 'apple' => 10, 'banana' => 5, 'orange' => 15 }

Retrieving Values

The get method retrieves the value associated with a specific key:

console.log(fruitMap.get("apple")); // 10
console.log(fruitMap.get("grape")); // undefined (key does not exist)

Checking for Keys

To check if a map contains a certain key, use the has method:

console.log(fruitMap.has("banana")); // true
console.log(fruitMap.has("mango")); // false

Removing Entries

You can remove a key-value pair using the delete method:

fruitMap.delete("banana");
console.log(fruitMap); // Map { 'apple' => 10, 'orange' => 15 }

If you wish to clear all entries from the map, use the clear method:

fruitMap.clear();
console.log(fruitMap.size); // 0

Iterating Over a Map

One of the powerful features of maps is their easy iteration capability. You can iterate over keys, values, or key-value pairs.

Using for...of

fruitMap.set("mango", 20);
fruitMap.set("pineapple", 25);
// Iterate over keys
for (let key of fruitMap.keys()) {
console.log(key); // mango, pineapple
}
// Iterate over values
for (let value of fruitMap.values()) {
console.log(value); // 20, 25
}
// Iterate over [key, value] pairs
for (let [key, value] of fruitMap.entries()) {
console.log(`${key}: ${value}`); // mango: 20, pineapple: 25
}

Using forEach

fruitMap.forEach((value, key) => {
console.log(`${key} -> ${value}`);
});
// Output:
// mango -> 20
// pineapple -> 25

Useful Map Properties

Size

The size property gives the number of key-value pairs present in a map:

console.log(fruitMap.size); // 2

Cloning and Merging Maps

Cloning a Map

You can easily clone a map by passing it to the Map constructor:

let clonedFruitMap = new Map<string, number>(fruitMap);
console.log(clonedFruitMap); // Map { 'mango' => 20, 'pineapple' => 25 }

Merging Two Maps

Merging two maps involves iterating over one and adding each entry to the other:

let additionalFruits = new Map([
['kiwi', 30],
['strawberry', 50]
]);
additionalFruits.forEach((value, key) => {
fruitMap.set(key, value);
});
console.log(fruitMap);
// Output: Map { 'mango' => 20, 'pineapple' => 25, 'kiwi' => 30, 'strawberry' => 50 }

When Should You Use a Map Over an Object?

  • Non-string keys: If you need keys that aren’t strings (e.g., objects, numbers), Map is the way to go.
  • Order preservation: Maps maintain the insertion order, while objects typically don’t guarantee any particular order.
  • Performance for large datasets: Maps offer better performance in scenarios where frequent addition, deletion, and checking for existence are required.

In conclusion, if you’re working on a TypeScript project and find yourself constrained by the limitations of plain objects for key-value storage, consider switching to Map. Its enhanced capabilities ensure your application's data management is efficient and robust. Whether it's the ease of operations or improved key flexibility, Map is an invaluable tool in every TypeScript developer's toolkit.

--

--

@rnab
@rnab

Written by @rnab

Typescript, Devops, Kubernetes, AWS, AI/ML, Algo Trading

No responses yet