How to Declare an ES6 Map in TypeScript
This tutorial guides us in defining the ES6 map in TypeScript with coding examples. This explains what the ES6 map is and its uses.
Let’s first see what ES6 is and why they are being used.
The ES6 Map
Before ES6, we used an object to emulate a map by mapping a key to a value of any type. However, an object as a map has some side effects:
- An object has a default key like the prototype.
- An object does not contain a property for representing the size of the map.
- An object key must be a string or a symbol. You cannot use an object for a key purpose.
ES6 provided a collection of new maps that deal with the above deficiencies. It can be defined as an object that holds key-value pairs where keys or values can be of any type.
Also, the map object remembers the original insertion of the order of the keys.
Syntax:
let dataMap = new Map([iterableObj]);
The map function only accepts an optional iterable object with elements in key-value pairs.
Consider the following code example with a person’s array of objects with key-value pairs.
Using the getElementById
query and calling the .innerHTML
function, we insert the person’s first name and last name by calling the Map
method on the iterable object by passing a callback function inside its parameter.
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Arrays</h2>
<p>Compute a new array with the full name of each person in the old array:</p>
<p id="demo"></p>
<script>
const persons = [
{firstname : "Malcom", lastname: "Reynolds"},
{firstname : "Kaylee", lastname: "Frye"},
{firstname : "Jayne", lastname: "Cobb"}
];
document.getElementById("demo").innerHTML = persons.map(getFullName);
function getFullName(item) {
return [item.firstname,item.lastname].join(" ");
}
</script>
</body>
</html>
Output:
Now, let us look at using the ES6 map in TypeScript.
Declare an ES6 Map as Record
in TypeScript
Instead of a map, the natively supported data type in TypeScript is Record
. TypeScript does not provide the polyfills for ES5, whereas in ES6, it allows using maps.
So when the TypeScript is compiled in ES5, it will use a natively supported type instead of a map, while in ES6, it can simply use the map. Consider the following example to describe Record
natively supporting the map.
interface IPerson{
}
type mapLikeType = Record<string, IPerson>;
const peopleA: mapLikeType = {
"a": { name: "joe" },
"b": { name: "bart" },
};
console.log(peopleA)
The above code contains the custom-defined map in the form of Record
with different key-value pairs. It produces the following output that restricts the peopleA
object from implementing the defined Record
type.
Output:
Since in lib.es6.d.ts
, the interface for map is defined, we can use it in TypeScript without defining the natively supporting types. The following is the interface:
interface Map<K, V> {
clear(): void;
delete(key: K): boolean;
entries(): IterableIterator<[K, V]>;
forEach(callbackfn: (value: V, index: K, map: Map<K, V>) => void, thisArg?: any): void;
get(key: K): V;
has(key: K): boolean;
keys(): IterableIterator<K>;
set(key: K, value?: V): Map<K, V>;
size: number;
values(): IterableIterator<V>;
[Symbol.iterator]():IterableIterator<[K,V]>;
[Symbol.toStringTag]: string;
}
interface MapConstructor {
new <K, V>(): Map<K, V>;
new <K, V>(iterable: Iterable<[K, V]>): Map<K, V>;
prototype: Map<any, any>;
}
declare var Map: MapConstructor;
Now, let us look at how to use a map in TypeScript directly, starting from creating an empty map by creating an initial key-value pair, then adding the entries and getting it and iterating all the values.
// Create Empty Map
let mapData = new Map<string, number>();
// Creating map with initial key-value pairs
let myMap = new Map<string, string>([
["key1", "value1"],
["key2", "value2"]
]);
// Map Operations
let nameAgeMapping = new Map<string, number>();
//1. Add entries
nameAgeMapping.set("Lokesh", 37);
nameAgeMapping.set("Raj", 35);
nameAgeMapping.set("John", 40);
//2. Get entries
let age = nameAgeMapping.get("John"); // age = 40
//3. Check entry by Key
nameAgeMapping.has("Lokesh"); // true
nameAgeMapping.has("Brian"); // false
//4. Size of the Map
let count = nameAgeMapping.size; // count = 3
//5. Delete an entry
let isDeleted = nameAgeMapping.delete("Lokesh"); // isDeleted = true
//6. Clear whole Map
nameAgeMapping.clear(); //Clear all entries
nameAgeMapping.set("Lokesh", 37);
nameAgeMapping.set("Raj", 35);
nameAgeMapping.set("John", 40);
//1. Iterate over map keys
for (let key of nameAgeMapping.keys()) {
console.log(key); //Lokesh Raj John
}
//2. Iterate over map values
for (let value of nameAgeMapping.values()) {
console.log(value); //37 35 40
}
//3. Iterate over map entries
for (let entry of nameAgeMapping.entries()) {
console.log(entry[0], entry[1]); //"Lokesh" 37 "Raj" 35 "John" 40
}
//4. Using object destructuring
for (let [key, value] of nameAgeMapping) {
console.log(key, value); //"Lokesh" 37 "Raj" 35 "John" 40
}
Ibrahim is a Full Stack developer working as a Software Engineer in a reputable international organization. He has work experience in technologies stack like MERN and Spring Boot. He is an enthusiastic JavaScript lover who loves to provide and share research-based solutions to problems. He loves problem-solving and loves to write solutions of those problems with implemented solutions.
LinkedIn