ProgrammationDéveloppeur Frontend

Comment fonctionne le mécanisme des types extensibles (signatures d'index) en TypeScript ? À quoi cela sert-il, quelles sont ses subtilités, et quels risques existent lors de la conception de telles structures ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Historique de la question

TypeScript permet de décrire des objets avec des noms de propriétés dynamiques, lorsqu'il est impossible de définir à l'avance toutes les clés. Pour cela, on utilise des signatures d'index, qui sont apparues comme un moyen de typage des objets variant (maps, données d'un serveur externe, etc.).

Problème

Sans signature d'index, un objet n'est perçu que par des clés prédéfinies, toutes les autres provoqueront une erreur de compilation. De plus, une déclaration incorrecte de signature peut brouiller les types de toutes les propriétés de l'objet, diminuer la rigueur des types et entraîner des bogues.

Solution

Déclarez explicitement la signature d'index uniquement là où cela est justifié. Pour le typage d'un tableau d'objets par clé de chaîne, utilisez la forme suivante :

Exemple de code :

interface Dictionary { [key: string]: number; length?: number; } const sample: Dictionary = { apples: 4, oranges: 10 }; sample['bananas'] = 6;

Caractéristiques clés :

  • Permet de décrire des collections avec des clés arbitraires
  • Basé sur un type unique pour toutes les valeurs des éléments
  • En raison de la signature, toutes les propriétés supplémentaires doivent correspondre à ce type

Questions piégées.

Peut-on définir différents types de valeurs pour différentes clés dans une signature d'index ?

Non, le type s'applique à l'ensemble du jeu de clés, si vous indiquez [key: string]: number, alors sample.length doit également être de type number : cela provoque souvent des erreurs lors de l'utilisation conjointe de la signature d'index et des propriétés connues.

Peut-on utiliser une signature d'index avec des symboles (symbol) ?

Oui, à partir de ES6, TypeScript prend en charge la signature d'index par symbole :

interface SymbolMap { [key: symbol]: string; }

Que se passe-t-il si l'on déclare un objet avec une signature d'index et des propriétés supplémentaires d'un autre type ?

Le compilateur renverra une erreur si le type de la propriété n'est pas compatible avec le type déclaré de la valeur de la signature d'index. Cela peut être contourné en utilisant un type union ou en séparant ces champs dans une interface distincte.

Erreurs typiques et anti-patrons

  • Utilisation excessive de la signature d'index au lieu d'interfaces strictes
  • Brouillage des types d'objets
  • Mauvaise combinaison de propriétés connues et d'index

Exemple de la vie réelle

Cas négatif

Pour toute réponse du serveur, on utilisait l'interface {[key: string]: any}, ce qui entraînait des bogues intrusifs en raison de la perte de contrôle sur la structure des données.

Avantages :

  • Universalité

Inconvénients :

  • Perte totale de la typage strict à l'intérieur de l'objet
  • Bogues cachés, « surprises » en production

Cas positif

Utilisation de la signature d'index strictement pour les dictionnaires (par exemple, configuration par clé), tandis que les propriétés connues sont déclarées hors de la signature.

Avantages :

  • Structure claire pour les collections/maps
  • La typage strict est conservée pour les champs connus

Inconvénients :

  • Nécessite plus de temps pour concevoir une architecture correcte des objets