TypeScript allows describing objects with dynamic property names when it is impossible to determine all keys in advance. This is done using index signatures, which emerged as a way to type object variants (maps, data from external servers, etc.).
Without an index signature, an object is perceived only by the predefined keys, and any others will trigger a compilation error. Additionally, an incorrect signature declaration can blur the types of all properties of the object, reduce type strictness, and lead to bugs.
Explicitly declare the index signature only where justified. For typing an array of objects by string key, use the following form:
Code example:
interface Dictionary { [key: string]: number; length?: number; } const sample: Dictionary = { apples: 4, oranges: 10 }; sample['bananas'] = 6;
Key features:
Can different value types be assigned for different keys in an index signature?
No, the type is uniform across the entire set of keys; if you specify [key: string]: number, then sample.length must also be a number: this often causes errors when combining index signatures and known properties.
Can an index signature be used with symbols?
Yes, starting from ES6 TypeScript supports index signatures by symbol:
interface SymbolMap { [key: symbol]: string; }
What happens if an object is declared with an index signature and additional properties of another type?
The compiler will produce an error if the property type is incompatible with the declared index signature value type. This can be worked around using a union type or moving such fields to a separate interface.
For any response from the server, an interface {[key: string]: any} was used, leading to penetrating bugs due to the loss of control over the data structure.
Pros:
Cons:
Using index signatures strictly for dictionaries (e.g., configuration by key), while explicitly known properties are declared outside the signature.
Pros:
Cons: