JavaScript

TypeScript Record vs Map: What’s Difference

In TypeScript, effective organization, storage, and retrieval of data are achieved through the utilization of data structures and mapped types. Among the frequently employed types for handling data collection are Record and Map, each possessing distinct strengths, use cases, and characteristics. Let us delve into a practical example to understand the TypeScript difference between Record and Map.

1. What is TypeScript?

TypeScript is a popular open-source programming language developed by Microsoft. It is a superset of JavaScript, adding optional static typing to the dynamic language. This means developers can write safer and more maintainable code by specifying data types for variables, function parameters, and return values. TypeScript code is compiled into plain JavaScript, ensuring compatibility with all JavaScript environments. It enhances productivity by providing features like type checking, interfaces, and advanced tooling for large-scale applications. TypeScript also supports modern ECMAScript features and can be used for both front-end and back-end development, making it a versatile choice for building robust and scalable web applications.

1.1 Record in TypeScript

In TypeScript, the Record type is a utility type that allows you to create an object type with specified keys and a uniform value type. It is particularly useful when you want to define a structure for an object where the keys are known in advance, and you want all values associated with those keys to have the same data type.

Here’s a basic syntax of the Record type:

Code Snippet

type MyRecord = Record<string, number>

In this example, MyRecord is a type that represents an object where all keys are strings, and the associated values are numbers. You can customize the type by changing the string or number to any other type that fits your requirements. Here’s an example of using Record in a practical scenario:

Code Snippet

type FruitCount = Record<string, number>;

const fruitBasket: FruitCount = {
  apple: 3,
  banana: 5,
  orange: 2,
};

// Valid
const appleCount: number = fruitBasket.apple;

// Error: Property 'grape' does not exist on type 'FruitCount'
const grapeCount: number = fruitBasket.grape;

In this example, FruitCount is a Record type defining that the keys must be strings, and the values must be numbers. When creating the fruitBasket object, TypeScript ensures that the keys are strings and the values are numbers. It also provides type safety when accessing properties, preventing attempts to access properties that are not defined in the FruitCount type.

1.1.1 When to use Record in TypeScript?

The Record type in TypeScript is particularly useful when you have a fixed set of keys and you want to ensure that values associated with those keys are of the same type. Here are some scenarios where using Record is appropriate:

  • Predefined Object Structure: When you have a well-defined structure for an object with known keys and a consistent value type.
  • Enums and Constants: When working with enums or constant values you want to create a mapping between keys and values.
  • Configuration Objects: When creating configuration objects with a fixed set of properties.
  • Static Lookup Tables: When defining static lookup tables where keys represent specific entities or categories.
  • Ensuring Consistency: When you want to ensure that all properties of an object have the same value type, providing type safety.

1.2 Map in TypeScript

In TypeScript, the Map type refers to a built-in JavaScript object that holds key-value pairs. It’s a data structure that allows you to associate values with keys and provides methods for easy manipulation of these key-value pairs. While the Map itself is a runtime construct in JavaScript, TypeScript includes type annotations to provide static typing for Map instances.

Here’s a basic usage of the Map type in TypeScript:

Code Snippet

// Creating a Map with string keys and number values
let myMap: Map<string, number> = new Map();

// Adding key-value pairs
myMap.set('one', 1);
myMap.set('two', 2);
myMap.set('three', 3);

// Retrieving values
const valueOne = myMap.get('one'); // valueOne is inferred as number | undefined

// Iterating through key-value pairs
myMap.forEach((value, key) => {
  console.log(<code>${key}: ${value}<code>);
});

In this example, myMap is a Map instance with string keys and number values. The Map provides methods like set for adding key-value pairs and get for retrieving values based on keys. TypeScript ensures that you are using the correct types when interacting with the Map, adding a layer of type safety.

Unlike the Record type, which is a static type declaration, the Map type is both a runtime construct and a type declaration in TypeScript. This means that when working with Map, you get the benefits of dynamic runtime behavior along with static type checking.

Here are a few key points about using Map in TypeScript:

  • Dynamic Key Types: Unlike Record, which requires predefined keys, Map allows you to use dynamically created keys.
  • Flexibility in Key Types: Map allows a wide range of key types, not limited to just strings or numbers.
  • Runtime Existence: Map is a runtime object in JavaScript, meaning it’s available and behaves the same way in both TypeScript and JavaScript.

1.2.1 When to use Map in TypeScript?

The Map type in TypeScript is a versatile data structure that provides dynamic key-value pair mappings. Here are situations where using Map is particularly beneficial:

  • Dynamic or unknown keys: Map is well-suited for scenarios where the keys are dynamic or not known in advance. Unlike Record, which requires predefined keys, Map allows you to use a wide range of key types.
  • Flexibility in Key Types: When you need flexibility in the types of keys used, such as using objects or other complex types as keys, Map provides a more flexible solution compared to Record.
  • Rich Set of Built-in Methods: Map comes with a variety of built-in methods like set, get, and delete. These methods make it easy to manipulate and interact with key-value pairs efficiently.
  • Order of Insertion: When the order of insertion is important, Map maintains the order of key-value pairs, making it suitable for use cases where the sequence of insertion matters.
  • Associative Data: For scenarios where you want to associate additional data with specific keys, Map allows you to store arbitrary data alongside the keys in a clean and organized way.
  • Use in Iteration: When you need to iterate over the keys or values in a collection, Map provides convenient methods like forEach that make iteration straightforward.

2. Difference between Record and Map

AspectRecordMap
DeclarationStatic type declarationRuntime object in JavaScript
Key TypesPredefined keys with a uniform value typeDynamic keys with a wide range of key types
Type SafetyType safety during object creation and property accessType safety during property access
Type AnnotationUses explicit type annotationsUses explicit type annotations
Data StorageStores data in a static structure with predefined keysStores data with dynamic keys and values
KeysKnown, fixed keysDynamic or varied keys
Value TypesUniform value type for all keysFlexible value types
Built-in MethodsLimited built-in methodsRich set of built-in methods (e.g., set, get, delete)
Order of InsertionMaintains order of key insertionDoes not guarantee the order of key insertion
Use CasesBest for situations with known, fixed keysFlexible for scenarios with dynamic or varied keys

3. Conclusion

In conclusion, the choice between TypeScript’s Record and Map types depends on the specific requirements and characteristics of your data structures. Use Record when dealing with a fixed set of keys and a uniform value type, providing static type safety and clarity in object structures. On the other hand, opt for Map when facing scenarios with dynamic or unknown keys, requiring a more flexible approach to key types and a rich set of built-in methods for efficient manipulation. Map excels in situations where the order of insertion matters, and it offers versatility in handling various data relationships. Understanding the distinctions between Record and Map empowers developers to make informed decisions, optimizing their TypeScript code based on the unique demands of each use case.

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button