Index Signatures
Type objects whose keys you don't know in advance, and mix them with known keys.
An index signature describes a dictionary: any key of a given type maps to a value of a given type. The keys can be string, number, or symbol.
interface StringMap {
[key: string]: number;
}
const counts: StringMap = {};
counts.apples = 3; // any string key, number valueMixing known and dynamic keys
You can pair fixed properties with an index signature β as long as every fixed property is assignable to the index's value type:
interface Config {
name: string; // fixed
[setting: string]: string | number; // plus arbitrary extras
}The safety caveat
An index signature quietly claims every key exists. map["typo"] is typed as present even when it is missing at runtime. Turning on noUncheckedIndexedAccess adds | undefined to each read and forces you to check β well worth it.
Example
When to use it
- A localisation module types its translation dictionary with a string index signature to accept any locale key.
- A metrics store uses [metricName: string]: number to hold an open-ended set of counter values.
- A form field error map is typed { [field: string]: string } to hold validation errors for any field name.
More examples
String index signature with known keys
Mixes required named keys with a string index signature, where the index type must be a superset of the named values.
interface Config {
host: string; // known key
port: number; // known key
[extra: string]: string | number; // dynamic keys must match union
}
const cfg: Config = { host: 'localhost', port: 5432, region: 'eu-west' };Readonly index signature
Marks the index signature readonly to prevent any key from being updated after the object is created.
interface ReadonlyMap {
readonly [key: string]: string;
}
const env: ReadonlyMap = { NODE_ENV: 'production', PORT: '8080' };
// env.NODE_ENV = 'dev'; // Error: index signature only permits readingNumber index signature
Uses a numeric index signature to model an array-like object, combined with a required length property.
interface NumberedList {
[index: number]: string;
length: number;
}
const list: NumberedList = { 0: 'a', 1: 'b', length: 2 };
console.log(list[0]); // 'a'
Discussion