TypeScript Index Signatures
Index signatures let you type objects whose exact property names aren't known ahead of time, such as dictionaries and dynamic lookup tables, while still keeping value types checked.
Basic Index Signatures
An index signature, written as [key: string]: ValueType inside an interface or type, tells TypeScript that any string key maps to a value of that type. It's the standard way to type dictionary-like objects.
A string-keyed dictionary
interface StringMap {
[key: string]: string;
}
const colors: StringMap = {
primary: "#0055ff",
secondary: "#333333",
};
colors.accent = "#ff9900"; // OK, any string key allowed
console.log(colors["primary"]); // "#0055ff"Numeric Index Signatures
A numeric index signature, [index: number]: ValueType, describes array-like structures. If an interface declares both a string and a number index signature, the numeric one's value type must be a subtype of the string one's.
Array-like access
interface FruitBasket {
[index: number]: string;
}
const basket: FruitBasket = ["apple", "banana", "mango"];
console.log(basket[1]); // "banana"Mixing Known Properties With an Index Signature
- Named, fixed properties must be compatible with the index signature's value type
- Combining Record<string, T> with specific keys via an intersection is a common escape hatch
- A readonly index signature prevents reassigning any indexed value after creation
- Every possible key is treated as accessible even if it doesn't exist at runtime, unless noUncheckedIndexedAccess is enabled
Fixed property plus dynamic settings
interface Config {
name: string; // must match the index signature's value type
[key: string]: string; // extra dynamic settings
}
const config: Config = {
name: "MyApp",
theme: "dark",
locale: "en-US",
};
// With noUncheckedIndexedAccess, this would type as string | undefined
const missing = config["doesNotExist"];
console.log(typeof missing); // "undefined" at runtimeExercise: TypeScript Index Signatures
What does the index signature `{ [key: string]: number }` allow?