DEV Community

Safal Bhandari
Safal Bhandari

Posted on

TypeScript: Choosing Between `Record` and `Map` for Key–Value Data

When you need to store collections of key–value pairs in TypeScript, two popular options are Record and Map. They serve similar purposes—both map keys to values—but differ in syntax, capabilities, and use-cases. Understanding these differences helps you pick the right tool for the job.


1. Using Plain Objects with Index Signatures

Traditionally, JavaScript objects are used as dictionaries:

interface User {
  id: string;
  name: string;
}

type Users = { [key: string]: User };

const users: Users = {
  abc123: { id: 'abc123', name: 'John Doe' },
  xyz789: { id: 'xyz789', name: 'Jane Doe' },
};

console.log(users['abc123']); // { id: 'abc123', name: 'John Doe' }
Enter fullscreen mode Exit fullscreen mode

The { [key: string]: User } syntax is called an index signature. It tells TypeScript that users can have any number of string keys, each mapping to a User.


2. Record<K, T> – A Cleaner Type Alias

Record is a built-in TypeScript utility type that makes the above pattern more concise:

interface User {
  id: string;
  name: string;
}

type Users = Record<string, User>;

const users: Users = {
  abc123: { id: 'abc123', name: 'John Doe' },
  xyz789: { id: 'xyz789', name: 'Jane Doe' },
};
Enter fullscreen mode Exit fullscreen mode

Benefits of Record:

  • Shorter, easier to read than an index signature.
  • Lets you constrain keys if you want a fixed set: type Roles = Record<'admin' | 'editor', User>;
  • Perfect for plain JSON-like objects where keys are strings (or numbers/symbols) known at compile time.

Limitations:

  • Keys are always strings (or a union of string literals).
  • Methods such as .size or ordered iteration aren’t built in—you treat it like a normal object.

3. Map<K, V> – A Full-Featured Key–Value Store

ECMAScript Map is a class that offers more flexibility than a plain object:

interface User {
  id: string;
  name: string;
}

const usersMap = new Map<string, User>();

usersMap.set('abc123', { id: 'abc123', name: 'John Doe' });
usersMap.set('xyz789', { id: 'xyz789', name: 'Jane Doe' });

console.log(usersMap.get('abc123')); // { id: 'abc123', name: 'John Doe' }
Enter fullscreen mode Exit fullscreen mode

Advantages of Map:

  • Keys can be any value, not just strings (objects, numbers, functions, etc.).
  • Maintains insertion order, which can be important for iteration.
  • Provides convenient methods: .get, .set, .has, .delete, .size, and built-in iterators.

Trade-offs:

  • Slightly more overhead than a plain object.
  • Not as easy to serialize to JSON directly (JSON.stringify won’t automatically include map entries).

4. When to Use Which

Scenario Prefer
Static or JSON-like data, simple string keys Record
Need arbitrary key types (objects, numbers, etc.) Map
Require ordered iteration or frequent insert/delete Map
Want lightweight, serializable structure Record

Quick Recap

  • Record<K, V>: TypeScript utility for object literals where keys are strings or a union of string literals. Clean and lightweight.
  • Map<K, V>: ECMAScript class with rich methods, supports any key type and preserves insertion order.

Choosing between them comes down to your requirements:

  • For configuration data, caching simple IDs, or working with JSON: Record (or an index signature) is perfect.
  • For dynamic, runtime-driven collections with complex keys or heavy mutation: Map is the better fit.

By understanding these tools, you can model key–value data in TypeScript with the right balance of simplicity and power.

Top comments (0)