Dictionnaires en TypeScript : du chaos à l'ordre (guide complet avec code)
\n\nImaginez que vous écrivez une application pour apprendre l'anglais. Vous devez stocker les traductions de mots : "cat" → "chat", "dog" → "chien". Quelle est la meilleure façon d'organiser ces données ? Bien sûr, utiliser un dictionnaire (Dictionary) — une structure de données où chaque clé est unique et associée à une valeur.
En JavaScript, les dictionnaires sont implémentés via des objets classiques ou Map. Mais TypeScript ajoute un typage puissant, transformant des collections chaotiques en structures strictes et prévisibles. Dans cet article, nous allons aborder la déclaration et l'initialisation d'un Dictionary en TypeScript du simple au complexe. Vous apprendrez à éviter les erreurs courantes et à écrire un code qui fonctionne de manière prévisible.
Qu'est-ce qu'un Dictionary en TypeScript ? (Et pourquoi ce n'est pas juste un objet)
\n\nEn programmation, un Dictionary (dictionnaire) est une collection de paires « clé-valeur ». En TypeScript, vous pouvez le créer de trois manières principales :
\n\n- \n
- Objet avec signature d'index (
{ [key: string]: T }) \n - Record — un type utilitaire \n
- Map — une classe ES6 intégrée \n
Chaque approche a ses avantages et ses nuances. Examinons-les avec des exemples concrets.
\n\nMéthode 1 : Objet classique avec signature d'index
\n\nLa façon la plus courante de déclarer un dictionnaire en TypeScript est d'utiliser une signature d'index. Cela indique au compilateur : « L'objet peut avoir un nombre quelconque de propriétés avec des clés d'un type spécifique ».
\n\n// Déclaration du type dictionnaire, où la clé est une chaîne et la valeur un nombre\ninterface DictionaryNumber {\n [key: string]: number;\n}\n\n// Initialisation\nconst ages: DictionaryNumber = {\n "Anna": 25,\n "Pierre": 30,\n "Hélène": 28\n};\n\n// Ajout d'un nouvel élément\nages["Olga"] = 35;\n\nconsole.log(ages["Anna"]); // 25\n\nImportant : TypeScript exige que toutes les valeurs correspondent au type déclaré. Tenter d'ajouter une chaîne provoquera une erreur de compilation :
\n\n// Erreur ! Le type 'string' ne peut pas être assigné au type 'number'\nages["Olga"] = "trente-cinq";\n\nQuand utiliser cette approche ?
\n- \n
- Quand vous avez besoin d'un dictionnaire simple et rapide \n
- Quand les clés sont des chaînes ou des nombres \n
- Pour de petites collections (jusqu'à 1000 éléments) \n
Méthode 2 : Record — une syntaxe élégante
\n\nTypeScript fournit le type utilitaire intégré Record<K, V>. Il crée un type d'objet où toutes les clés sont de type K et les valeurs de type V.
// Déclaration et initialisation en une ligne\nconst grades: Record<string, number> = {\n "Mathématiques": 5,\n "Physique": 4,\n "Histoire": 5\n};\n\n// On peut utiliser une énumération pour les clés\nenum Subject {\n Math = "math",\n Physics = "physics",\n History = "history"\n}\n\nconst gradesBySubject: Record<Subject, number> = {\n [Subject.Math]: 5,\n [Subject.Physics]: 4,\n [Subject.History]: 5\n};\n\nAvantages de Record :
\n- \n
- Syntaxe concise \n
- Bonne lisibilité \n
- Prise en charge des types union pour les clés \n
Méthode 3 : Map — pour les scénarios avancés
\n\nLa classe Map d'ES6 est une collection complète de paires « clé-valeur » avec des fonctionnalités supplémentaires. En TypeScript, on la type à l'aide de génériques :
// Déclaration d'un Map\nconst userRoles: Map<string, string> = new Map([\n ["admin", "Administrateur"],\n ["user", "Utilisateur"],\n ["guest", "Invité"]\n]);\n\n// Ajout\nuserRoles.set("moderator", "Modérateur");\n\n// Récupération\nconsole.log(userRoles.get("admin")); // "Administrateur"\n\n// Vérification de présence\nif (userRoles.has("user")) {\n console.log("Le rôle existe");\n}\n\n// Et