Map en TypeScript : une collection clé-valeur typée
Map en TypeScript
Map en TypeScript : typer, parcourir et sauvegarder une Map | We.Inc
Typez une Map<K, V> en TypeScript, parcourez-la, convertissez-la en JSON et inversement, et choisissez entre Map, Record et un objet simple. Essayez une Map en direct dans le navigateur.
En TypeScript, une Map est la Map JavaScript ordinaire avec des types pour ses clés et ses valeurs : new Map<string, number>(). Les clés peuvent être n'importe quelle valeur, les entrées reviennent dans l'ordre où elles ont été ajoutées la première fois, size les compte, et get renvoie V | undefined. JSON.stringify ne sérialise pas une Map, il faut donc la convertir d'abord.
Les méthodes de Map et ce que renvoie TypeScript
Appel
Effet
Type obtenu (Map<string, number>)
map.set(k, v)
Ajoute ou met à jour une entrée
Map<string, number> (chaînable)
map.get(k)
Lit une valeur
number | undefined
map.has(k)
Vérifie une clé
map.delete(k)
Supprime une entrée
boolean (true si elle existait)
Compte les entrées
for (const [k, v] of map)
Parcourt dans l'ordre d'insertion
k: string, v: number
Le bac à sable ci-dessous est une vraie Map qui tourne dans votre navigateur. Ajoutez, modifiez et supprimez des entrées, et observez trois choses : l'ordre que gardent les entrées, la valeur de size, et la différence entre sérialiser la Map elle-même et sérialiser une copie convertie.
Saisissez une clé et un nombre, puis appuyez sur Définir pour ajouter ou mettre à jour cette entrée.
Appuyez sur Supprimer pour retirer la clé indiquée dans le champ clé, ou sur Vider pour vider la Map.
Lisez la liste des entrées, qui suit l'ordre d'itération propre à la Map.
Comparez les deux lignes JSON pour comprendre pourquoi une Map doit être convertie avant d'être sauvegardée ou envoyée.
Indiquez les arguments génériques quand vous créez une Map vide. new Map() seul donne Map<any, any>, et chaque lecture ultérieure perd son type.
Vérifiez has() ou comparez get() à undefined avant d'utiliser une valeur. Une assertion non-null masque le cas où la clé est vraiment absente.
Les clés objets sont comparées par référence. Deux objets aux mêmes champs sont deux clés différentes : utilisez une chaîne d'id quand vous parlez du même enregistrement.
Pour garder une Map dans localStorage, stockez JSON.stringify([...map]) et reconstruisez-la avec new Map(JSON.parse(text)). Le tableau de paires conserve les clés non textuelles et l'ordre.
Questions fréquentes
Comment déclarer le type d'une Map en TypeScript ?
Passez les types de clé et de valeur comme arguments génériques : const prices = new Map<string, number>(). Pour un champ ou un paramètre, écrivez le type Map<string, number>, ou ReadonlyMap<string, number> quand la fonction doit seulement la lire.
Pourquoi le type de map.get() inclut-il undefined ?
Parce que le compilateur ne peut pas savoir quelles clés se trouvent dans la Map à un moment donné. get est typé V | undefined, donc vous affinez le type avec un test if, une valeur de repli ?? ou un test has() avant de traiter la valeur comme V.
Pourquoi JSON.stringify(map) donne-t-il {} ?
Une Map garde ses entrées dans un emplacement interne, pas comme propriétés d'objet, donc JSON voit un objet vide. Convertissez d'abord : Object.fromEntries(map) pour des clés textuelles, ou [...map] pour un tableau de paires qui supporte tout type de clé.
Faut-il utiliser une Map ou un Record ?
Utilisez un Record pour un ensemble fixe de clés nommées et pour des données qui transitent depuis et vers JSON. Utilisez une Map quand les entrées apparaissent et disparaissent pendant l'exécution de l'app, quand les clés sont des nombres ou des objets, ou quand l'ordre d'insertion compte.
Mettre à jour une clé la déplace-t-elle à la fin ?
Non. Définir une clé existante change sa valeur mais conserve sa position d'origine. Pour la déplacer à la fin, supprimez la clé puis définissez-la à nouveau.
Map, Record et objet simple
Un objet simple hérite de Object.prototype, donc des noms comme constructor y existent déjà, et ses clés sont toujours des chaînes ou des symboles. Une Map démarre vide, accepte n'importe quelle valeur comme clé et indique son nombre d'entrées via size.
Record est un type, pas un conteneur. Il décrit un objet simple : tout ce qui précède sur les objets s'y applique à l'exécution, y compris la prise en charge native de JSON qui manque à une Map.
Comment les clés sont comparées
Map compare les clés selon la règle SameValueZero. Le nombre 1 et la chaîne "1" sont des clés différentes, NaN correspond à NaN, et un objet ne correspond qu'à lui-même. Un objet simple transformerait 1 en "1" et fusionnerait les deux.
Cela fait de la Map le cache naturel pour des valeurs indexées par un élément du DOM, une fonction ou un objet de requête, des cas où un objet exigerait d'inventer un id textuel.
Typer les Maps dans les signatures de fonction
Acceptez ReadonlyMap<K, V> dans les fonctions qui ne font que lire. Ce type retire set, delete et clear, si bien que la signature indique d'elle-même aux appelants que leur Map ne sera pas modifiée.
Quand vous construisez une Map à partir d'un tableau de paires, TypeScript déduit les types à partir des paires. Ajoutez un générique explicite quand le tableau peut être vide ou quand les paires mélangent des types que vous voulez garder séparés.
Recettes de Map typées
Compter des mots avec une Map
La valeur de repli ?? gère la première apparition d'un mot, ce qui explique pourquoi un get renvoyant number | undefined est utile plutôt que gênant.
Sauvegarder une Map en JSON et la recharger
Un tableau de paires conserve chaque entrée et son ordre. Object.fromEntries est le choix le plus lisible quand toutes les clés sont des chaînes.
Accepter une Map en lecture seule
Dans total, appeler prices.set provoquerait une erreur de compilation, donc les appelants peuvent passer leur Map sans copie défensive.
Bac à sable Map en direct
Clé
Valeur (nombre)
Définir
Supprimer
Vider
Réinitialiser
Entrées dans l'ordre d'itération
La Map est vide.
size : {n}
"{v}" ajouté.
"{v}" supprimé.
"{v}" n'est pas dans la Map, donc delete a renvoyé false.