L'Index Signature est un mécanisme de description du type des objets dont les clés sont inconnues à l'avance (ou peuvent être ajoutées dynamiquement), et dont les valeurs correspondent à un type défini. Cela permet de créer des objets-dictionnaires (map/dictionary), où la liste des propriétés n'est pas connue au moment de la compilation.
Contexte : dans JavaScript, les objets agissent souvent en tant que tableaux associatifs. La typage statique de TypeScript exige de spécifier les types des clés et des valeurs. L'Index Signature résout le problème principal : décrire un objet où la clé n'est pas une propriété durcie, mais une chaîne (ou un nombre), tandis que les valeurs sont d'un type défini.
Problème : lors de l'utilisation de tels objets, il est possible de se retrouver dans une situation où les propriétés connues de l'objet entrent en conflit avec l'index signature, ou où l'information sur les propriétés spécifiques est perdue. Il y a des nuances concernant les types hérités et l'extension de la structure du dictionnaire.
Solution : L'Index Signature est utilisé pour décrire des propriétés dynamiques, généralement avec une clé de type string ou number, par exemple pour des collections, des objets cache ou des réponses API sous la forme { [key: string]: T }. Pour garder le contrôle sur le type, il est nécessaire de décrire à la fois les propriétés fixes et l'index signature ensemble, ou si besoin — de constituer des types unions.
Exemple de code :
interface StringNumberMap { [key: string]: number; } const map: StringNumberMap = { apples: 2, oranges: 5, bananas: 3 };
Caractéristiques clés :
Que se passera-t-il si l'on ajoute une propriété fixe avec un type incompatible dans une interface avec une index signature ?
TypeScript renverra une erreur si le type de la propriété n'est pas compatible avec le type spécifié dans l'index signature.
interface BadDict { [key: string]: number; error: string; // Erreur : string n'est pas compatible avec number }
Peut-on déclarer plusieurs index signatures avec différents types de clés (number et string) en même temps ?
Oui, c'est possible, mais il y a une nuance : dans TypeScript, les clés de type number sont automatiquement converties en chaîne. L'index signature avec number n'est qu'un synonyme pour les clés de type string.
interface NumStrDict { [key: string]: number; [key: number]: number; }
Peut-on utiliser des types union ou des interfaces pour la valeur dans une index signature ?
Oui, la valeur peut être d'un type union ou d'une interface. Ainsi, il est possible de décrire des dictionnaires d'objets complexes.
interface Dict { [key: string]: string | number; }
Dans l'interface de réponse API, on a utilisé [key: string]: any. Plus tard, l'objet retourné contenait des données de différentes structures, ce qui a entraîné des erreurs à l'exécution et a compliqué la maintenance du code.
Avantages :
Inconvénients :
On a décrit une interface d'objet cache, où les valeurs sont d'un type strictement défini (par exemple, UserData), avec un commentaire précisant que la clé est userId (string) :
interface UserCache { [userId: string]: UserData; }
Avantages :
Inconvénients :