# How to Use a TypeScript Map: ES6 Collections with Static Typing

> Master TypeScript Maps for type-safe ES6 collections. Learn to leverage generic parameters K and V effectively for robust key-value storage in your applications.

- Repository: [Microsoft/TypeScript](https://github.com/microsoft/typescript)
- Tags: tutorial
- Published: 2026-02-12

---

**A TypeScript Map is a strongly-typed wrapper around JavaScript's ES6 Map collection that enforces type safety for keys and values through generic parameters `K` and `V` defined in the standard library declaration files.**

The TypeScript compiler adds static type checking to JavaScript's native ES6 Map through declaration files found in the `microsoft/TypeScript` repository. These type definitions allow developers to create maps with compile-time guarantees that keys and values match specified types, preventing runtime errors while maintaining full compatibility with the underlying JavaScript runtime.

## Core TypeScript Map Interface Declaration

In [`src/lib/es2015.collection.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es2015.collection.d.ts), TypeScript defines the `Map<K, V>` interface using generic parameters where `K` represents the key type and `V` represents the value type. This interface describes the exact shape of the runtime ECMAScript 2015 Map object while adding compile-time type enforcement.

```typescript
interface Map<K, V> {
    /** Returns the number of entries in the map. */
    readonly size: number;

    /** Adds a new entry or updates an existing one. */
    set(key: K, value: V): this;

    /** Retrieves the value for a given key – returns undefined if the key is absent. */
    get(key: K): V | undefined;

    /** Returns true if the map contains the given key. */
    has(key: K): boolean;

    /** Removes an entry. Returns true if the entry existed. */
    delete(key: K): boolean;

    /** Removes all entries. */
    clear(): void;

    /** Returns an iterator over the map’s keys. */
    keys(): IterableIterator<K>;

    /** Returns an iterator over the map’s values. */
    values(): IterableIterator<V>;

    /** Returns an iterator over [key, value] tuples. */
    entries(): IterableIterator<[K, V]>;

    /** Default iterator – same as `entries()`. */
    [Symbol.iterator](): IterableIterator<[K, V]>;

    /** Executes a callback for each entry. */
    forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
}

```

### Key Methods and Properties

- **`get(key: K)`**: Returns `V | undefined` because JavaScript Map returns undefined for missing keys, forcing explicit handling of absent values.
- **`set(key: K, value: V)`**: Returns `this` to enable method chaining while enforcing type constraints.
- **`has(key: K)`**: Returns boolean without consuming the value, useful for existence checks.
- **`delete(key: K)`**: Returns boolean indicating whether the key existed before deletion.
- **`readonly size`**: Property tracking entry count, marked readonly as mutation only occurs through `set` and `delete`.

## MapConstructor and Map Creation

TypeScript models the JavaScript Map constructor through the `MapConstructor` interface in the same declaration file. This interface describes how to instantiate maps from iterables of tuples or create empty typed collections.

```typescript
interface MapConstructor {
    /** Creates a new empty map. */
    new <K, V>(entries?: readonly (readonly [K, V])[] | null): Map<K, V>;

    /** The prototype property of the Map constructor. */
    readonly prototype: Map<any, any>;

    /** Returns a new map that contains the same entries as the iterable. */
    from<K, V>(iterable: Iterable<[K, V]>): Map<K, V>;
}
declare const Map: MapConstructor;

```

The generic constructor allows initialization with explicit types: `new Map<string, number>()` creates an empty map where the compiler ensures string keys always map to number values.

## Practical TypeScript Map Examples

The following examples demonstrate type-safe Map usage according to the Microsoft/TypeScript source definitions:

### Creating and Mutating Typed Maps

```typescript
// 1️⃣ Creating a typed map
const scores = new Map<string, number>();

// Adding entries – type-checked at compile time
scores.set('Alice', 42);
scores.set('Bob', 37);

// 2️⃣ Reading values – the return type is `number | undefined`
const aliceScore = scores.get('Alice'); // 42
const unknownScore = scores.get('Eve');  // undefined

```

### Iterating Over Entries

```typescript
// 3️⃣ Iterating over a map
for (const [name, score] of scores) {
    console.log(`${name} scored ${score}`);
}
// Output:
// Alice scored 42
// Bob scored 37

```

### Using Objects as Keys

```typescript
// 4️⃣ Using a map with object keys
interface Point { x: number; y: number }
const pointMap = new Map<Point, string>();
const p1: Point = { x: 0, y: 0 };
pointMap.set(p1, 'origin');
console.log(pointMap.get(p1)); // "origin"

```

### Initializing from Arrays

```typescript
// 6️⃣ Initialising from an array of entries
const colors = new Map<string, string>([
    ['red', '#ff0000'],
    ['green', '#00ff00'],
    ['blue', '#0000ff'],
]);
console.log(colors.get('green')); // "#00ff00"

```

## ReadonlyMap for Immutable Collections

TypeScript provides a `ReadonlyMap<K, V>` interface (defined in [`src/lib/es2015.collection.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es2015.collection.d.ts)) that exposes the same read methods as Map but omits mutating methods (`set`, `delete`, `clear`). This pattern is essential for function parameters where you want to prevent modification of the passed map.

```typescript
// 5️⃣ Read-only view – useful for API boundaries
function logAll(map: ReadonlyMap<string, number>) {
    map.forEach((value, key) => console.log(`${key}: ${value}`));
}
logAll(scores); // OK
// scores.set('Eve', 10); // ❌ compile-time error outside this scope

```

Attempting to call mutating methods on a `ReadonlyMap` parameter results in a compile-time error, enforcing immutability at the type level.

## Source Files in the TypeScript Repository

The type definitions for Map are distributed across lib files that ship with the compiler:

- **[`src/lib/es2015.collection.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es2015.collection.d.ts)**: Core ES2015 Map interface and MapConstructor definitions used when targeting ES2015 or higher.
- **[`src/lib/esnext.collection.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/esnext.collection.d.ts)**: Extended collection typings for newer ECMAScript targets, including additional iterator protocol symbols.
- **[`src/lib/lib.es2022.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/lib.es2022.d.ts)**: Aggregates and re-exports collection types for specific lib references, ensuring `/// <reference lib="es2022"/>` pulls the correct Map shape.

These files contain **only type declarations**—they describe the contract that your TypeScript code must satisfy, while the actual Map implementation is provided by the JavaScript engine at runtime.

## Summary

- TypeScript Map types are declared in [`src/lib/es2015.collection.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es2015.collection.d.ts) using generic interfaces `Map<K,V>` and `MapConstructor` that mirror the JavaScript ES6 Map API.
- The `K` and `V` generic parameters enforce compile-time type safety for all keys and values stored in the map, preventing type mismatches before execution.
- Method signatures like `get()`, `set()`, and `has()` are typed to ensure operations use correct types, with `get()` returning `V | undefined` to handle missing keys safely.
- `ReadonlyMap<K,V>` provides an immutable view suitable for function parameters and API boundaries where mutation must be prevented.
- At runtime, TypeScript compiles down to JavaScript's native ES6 Map implementation, incurring no performance overhead from the type layer.

## Frequently Asked Questions

### What is the difference between a TypeScript Map and a JavaScript Map?

There is no runtime difference—TypeScript Map types are compile-time annotations that describe JavaScript's native ES6 Map. The TypeScript compiler uses declaration files like [`src/lib/es2015.collection.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es2015.collection.d.ts) to verify that your code respects the generic type parameters `K` and `V`, then erases these types when generating JavaScript, leaving the standard Map implementation to handle execution.

### How do you initialize a TypeScript Map with data?

Use the Map constructor with an array of key-value tuples and explicit generic type parameters: `new Map<string, number>([['Alice', 42], ['Bob', 37]])`. TypeScript validates that each tuple matches the declared key and value types, ensuring the map is correctly typed from initialization.

### Can you use objects as keys in a TypeScript Map?

Yes, the Map interface accepts any type for `K`, including objects and functions. When you declare `Map<Point, string>`, TypeScript allows object references as keys while ensuring associated values match the string type, leveraging JavaScript's reference-based equality for object keys.

### Why does a TypeScript Map return undefined for missing keys?

The `get(key: K)` method signature returns `V | undefined` because the JavaScript Map specification mandates returning `undefined` for absent keys. This union type forces developers to handle the undefined case explicitly in TypeScript, preventing null pointer exceptions that might occur if the type system assumed a value always existed.