You can create a Map from an array in TypeScript by passing an array of [key, value] pairs to new Map(). For an array of objects, turn each object into a pair with map() first, and TypeScript infers the key and value types for you:
const byId = new Map(customers.map((c) => [c.id, c])); // Map<number, Customer>
These snippets were checked with TypeScript 7.0.2 with Node.js v22.22.2 in strict mode, so the types and errors you see are what the compiler really reports.
We’ll build Maps from pairs and from objects, see what happens with duplicate keys, handle the undefined that get() can return, group items with Map.groupBy(), and count values.
Create a Map from an array of key-value pairs
new Map() accepts any iterable of two-item arrays. Type the pairs as tuples, [string, number][], and you get a Map<string, number>:
const pairs: [string, number][] = [
["Austin", 8.25],
["Denver", 8.81],
["Seattle", 10.35],
];
const taxRates = new Map(pairs); // Map<string, number>
console.log(taxRates);
console.log("Denver:", taxRates.get("Denver"), "| size:", taxRates.size);
const dupes = new Map([["TX", "Austin"], ["CO", "Denver"], ["TX", "Dallas"]]);
console.log(dupes); // the last "TX" wins
Output:
Map(3) { 'Austin' => 8.25, 'Denver' => 8.81, 'Seattle' => 10.35 }
Denver: 8.81 | size: 3
Map(2) { 'TX' => 'Dallas', 'CO' => 'Denver' }

size work right away. When a key repeats, the last value overwrites the earlier one.Duplicate keys don’t throw, so check your data first if each key must be unique. Finding repeats is covered in removing duplicates from an array of objects.
Create a Map from an array of objects (keyed by id)
This is the case I use most: fast lookups by id instead of searching the array every time. Return a pair from map() and pass the result to new Map():
interface Customer {
id: number;
name: string;
state: string;
}
const customers: Customer[] = [
{ id: 101, name: "Emily Clark", state: "TX" },
{ id: 102, name: "James Lee", state: "CO" },
{ id: 103, name: "Olivia Diaz", state: "FL" },
];
const byId = new Map(customers.map((c) => [c.id, c])); // Map<number, Customer>
const nameById = new Map(customers.map((c) => [c.id, c.name] as const));
console.log(byId.get(102));
console.log(nameById);
console.log("has 104?", byId.has(104));
Output:
{ id: 102, name: 'James Lee', state: 'CO' }
Map(3) {
101 => 'Emily Clark',
102 => 'James Lee',
103 => 'Olivia Diaz'
}
has 104? false

has() answers membership in constant time.The as const keeps [c.id, c.name] a tuple instead of widening it to (string | number)[]. If you’d rather keep a plain object, a TypeScript Record type does a similar job for string keys.
Why does Map.get() return undefined in TypeScript?
get() returns V | undefined, because the key might not be there. With --strict, using the result directly is an error:
interface Customer { id: number; name: string; }
const byId = new Map<number, Customer>([[101, { id: 101, name: "Emily Clark" }]]);
const customer = byId.get(101);
console.log(customer.name.toUpperCase());
Output:
map_get_undefined.ts(5,13): error TS18048: 'customer' is possibly 'undefined'.

Check the value, or use optional chaining with a fallback:
interface Customer { id: number; name: string; }
const byId = new Map<number, Customer>([[101, { id: 101, name: "Emily Clark" }]]);
const customer = byId.get(101);
if (customer) {
console.log(customer.name.toUpperCase());
}
console.log(byId.get(999)?.name ?? "unknown customer");
Output:
EMILY CLARK
unknown customer
Avoid the ! non-null assertion unless you’ve just called has(). It silences the compiler without protecting you at runtime. Similar checks for plain objects are in checking if a key exists in a TypeScript object.
Group array items into a Map with Map.groupBy()
Map.groupBy() (ES2024) puts items into arrays under a key you compute. TypeScript needs es2024 in lib; with an older lib the method doesn’t exist yet:
const orders = [
{ id: "A-1001", state: "TX", total: 59.99 },
{ id: "A-1002", state: "CA", total: 120.0 },
{ id: "A-1003", state: "TX", total: 35.5 },
];
const byState = Map.groupBy(orders, (o) => o.state);
console.log(byState);
Output:
map_groupby.ts(6,21): error TS2550: Property 'groupBy' does not exist on type 'MapConstructor'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2024' or later.
map_groupby.ts(6,38): error TS7006: Parameter 'o' implicitly has an 'any' type.
With --lib es2024 it compiles, and Node.js 21 or later runs it:
const orders = [
{ id: "A-1001", state: "TX", total: 59.99 },
{ id: "A-1002", state: "CA", total: 120.0 },
{ id: "A-1003", state: "TX", total: 35.5 },
];
const byState = Map.groupBy(orders, (o) => o.state);
console.log(byState);
for (const [state, list] of byState) {
const sum = list.reduce((s, o) => s + o.total, 0);
console.log(`${state}: ${list.length} order(s), $${sum.toFixed(2)}`);
}
Output:
Map(2) {
'TX' => [
{ id: 'A-1001', state: 'TX', total: 59.99 },
{ id: 'A-1003', state: 'TX', total: 35.5 }
],
'CA' => [ { id: 'A-1002', state: 'CA', total: 120 } ]
}
TX: 2 order(s), $95.49
CA: 1 order(s), $120.00

es2023 and works with es2024, grouping orders by state with totals.On older targets, the same grouping takes a few lines with the TypeScript reduce method and map.set().
Count occurrences with a Map
Counting is the other everyday job. Read the current count with get(), default it to 0 with ??, and set it back:
const visits = ["Austin", "Denver", "Austin", "Miami", "Austin", "Denver"];
const counts = new Map<string, number>();
for (const city of visits) {
counts.set(city, (counts.get(city) ?? 0) + 1);
}
console.log(counts);
const counts2 = visits.reduce(
(m, city) => m.set(city, (m.get(city) ?? 0) + 1),
new Map<string, number>(),
);
console.log([...counts2].sort((a, b) => b[1] - a[1])[0], "is the most visited");
Output:
Map(3) { 'Austin' => 3, 'Denver' => 2, 'Miami' => 1 }
[ 'Austin', 3 ] is the most visited
Because set() returns the Map itself, it also works as the accumulator inside reduce(). To turn the result back into an array for sorting or display, see converting a Map to an array in TypeScript.
Map vs object when you build from an array
| Need | Use |
|---|---|
| Keys that aren’t strings (numbers, objects) | Map |
Frequent adds and deletes, size | Map |
| Plain JSON in and out | Object / Record |
| Fixed set of known keys | Object type or Record with a union |
These guides fit well with Maps:
- Iterate over a Record in TypeScript
- Mapped types in TypeScript
- Arrays of objects in TypeScript
- Sum an array in TypeScript
Frequently asked questions
How do I create a Map from an array in TypeScript?
Pass an array of [key, value] pairs to new Map(). For objects, use new Map(items.map((i) => [i.id, i])).
How do I type a Map created from an array?
Usually TypeScript infers it. You can also write new Map<number, Customer>(...) or type the pairs as tuples.
What happens with duplicate keys?
The last pair with that key wins; earlier values are overwritten without an error.
Why is Map.get() possibly undefined?
The key may be missing, so the return type is V | undefined. Check the value or use ?. and ??.
Why doesn’t Map.groupBy exist in my TypeScript project?
Add es2024 (or newer) to lib in tsconfig.json, and run on Node.js 21 or later.
Where is the Map constructor documented?
See Map() constructor on MDN.

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn