TypeScript Record vs Map: What’s Difference?

In TypeScript, for efficient data structuring, storage and retrieval, we use data structures and mapped types. The Record and Map are among the most commonly used types for managing collections of data. Both have their own strengths, use cases, and characteristics.

This article explores the syntax, provides simple examples, and outlines the differences between Record and Map types. This knowledge will help us in using these constructs effectively and make more informed decisions.

1. Introduction to Record and Map

Let us begin with a simple introduction to each construct and a simple example. Later we will delve into their differences.

1.1. Record Type

The Record type enables us to define precise object shapes with specific key-value types. It exists as an additional type, such as classes or interfaces, to encapsulate data & behavior and ensure type safety for the object’s structure.

Note that the primary difference between Class and Record is that records are used for modeling structured data with a consistent format whereas classes are created to encapsulate data and behavior and offer inheritance, encapsulation, and polymorphism.

In the following example, we declare a new type named Person of type Record which declares the shape of the Person objects. In this case, the keys of the object are of type string, and the values can be either of type string or number.

type Person = Record<string, string | number>;

The following code declares a constant variable named alice with the type Person. This means that alice must adhere to the structure defined by the Person type. Then we initialize the alice object with concrete values of the keys.

const alice: Person = {
    name: "Alice",
    age: 30,
};

1.2. Map Data Structure

Contrary to a Record which is a type, a Map is a full-fledged data structure for storing the key-value pairs. It provides dedicated methods for adding, retrieving, and deleting entries from the Map.

Unlike object types such as Record, a Map can store any type of value including objects, functions, and other primitives.

We can create a new Map instance using the Map constructor.

let myMap = new Map<string, number>();

Then we can add, update or delete entries from the Map using its inbuilt methods.

myMap.set("Lokesh", 37);
myMap.set("Raj", 35);

//Get value by key
let age = myMap.get("Lokesh");	// age = 37

//Check entry by Key
myMap.has("Lokesh");		// true

//Delete entry by key 
let isDeleted = myMap.delete("Lokesh");

2. Difference between Record and Map

Now that we have a basic understanding of both types, let us identify their differences:

FeatureRecordMap
Type AnnotationDefines object shapes with specific key-value types.Standard data structure to store key-value pairs with varying types.
Data StorageEmphasizes structured data representation.Focuses on dynamic data storage and retrieval.
KeysUses string literals as keys.Supports keys of any data type.
Value TypesAll values must have the same type.Values can be of different types.
Built-in MethodsLacks built-in iteration methods.Provides built-in methods for adding, retrieving, and iterating the entries.
Order of InsertionOrder of properties not guaranteed.Maintains the insertion order of entries.
Use CasesSuitable for structured data definitions.Ideal for storing dynamic data in the form of key-value pairs.

3. When to use?

Let’s explore some practical examples of when to use Map and Record in TypeScript.

3.1. Use Record for Structured Data

Record is particularly useful when we want to define a specific structure for an object with string keys and a consistent value type, and it doesn’t require the dynamic behavior of methods or additional functionality.

For example, in a video player app, users can configure their playback settings, such as volume, subtitles, and playback speed. These settings always adhere to a well-defined structure, and often we don’t need methods to mutate their content.

type PlaybackSettings = Record<string, string | number | boolean>;

class VideoPlayer {
    private settings: PlaybackSettings = {};

    updateSettings(key: string, value: string | number | boolean): void {
        this.settings[key] = value;
    }

    getSettings(): PlaybackSettings {
        return { ...this.settings };
    }
}

const player = new VideoPlayer();

player.updateSettings("volume", 70);
player.updateSettings("subtitles", true);

console.log(player.getSettings());
// Output: { volume: 70, subtitles: true }

3.2. Use Map to store Dynamic Data

We should use Map when we need to store dynamic key-value pairs, especially if we require the support of built-in methods for adding and manipulating the collection of data.

For example, a user is adding random items to his/her shopping cart. In this case, we can store the item IDs as Map keys, and item quantities as Map values. The built-in methods will immensely help in keeping the data in sync when a user adds or removes new items or existing items from his cart. Keeping such data in Map helps in managing items in the cart, in more simpler way.

class ShoppingCart {

  private cartItems: Map<string, number> = new Map();

  addItemToCart(itemID: string, quantity: number): void {
    if (this.cartItems.has(itemID)) {
      const currentQuantity = this.cartItems.get(itemID)!;
      this.cartItems.set(itemID, currentQuantity + quantity);
    } else {
      this.cartItems.set(itemID, quantity);
    }
  }

  removeItemFromCart(itemID: string, quantity: number): void {
    if (this.cartItems.has(itemID)) {
      const currentQuantity = this.cartItems.get(itemID)!;
      const newQuantity = Math.max(currentQuantity - quantity, 0);
      if (newQuantity === 0) {
        this.cartItems.delete(itemID);
      } else {
        this.cartItems.set(itemID, newQuantity);
      }
    }
  }

  getCartContents(): Map<string, number> {
    return new Map(this.cartItems);
  }
}

const userCart = new ShoppingCart();

userCart.addItemToCart("item001", 2);
userCart.addItemToCart("item002", 1);
userCart.addItemToCart("item001", 1); // Adding more of an existing item

4. Conclusion

As discussed in the article, both Record and Map serve distinct purposes and offer unique advantages based on the specific usecases. The Record type shines when we want to define a specific structure for objects with string keys and consistent value types. On the other hand, the Map data structure excels in dynamic data storage and manipulation scenarios.

Happy Learning!!

Comments

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.