Index signatures
📚 What are Index Signatures in TypeScript? When you need an object that can have any number of string keys all mapping to the same value type -- like a dictionary -- you use an index signature: { [key: string]: number }. This says: 'this object can have any string as a key, and every value will be…

Appy Says…
Sometimes you don't know the exact property names ahead of time — you just know they'll all be strings mapping to numbers, or strings mapping to strings. Index signatures let you type these dynamic objects.
What are Index Signatures?
An index signature describes objects with dynamic keys — you specify the key type and value type, without listing every property name.
- •Syntax:
{ [key: string]: ValueType } - •
interface StringMap { [key: string]: string; } - •
const headers: StringMap = { 'Content-Type': 'application/json' }; - •Index signature means ANY string key maps to that type
- •Can combine with specific properties:
{ id: number; [key: string]: string | number; } - •Record type (cleaner alternative):
Record<string, string>— same as index signature
Think of it like a Minecraft chest that holds only diamonds
You don't know what's in every slot — slots are dynamic. But you know every slot either has diamonds or is empty. An index signature types this: 'I don't know the keys, but every value is a diamond (the declared type)'.
How It Works
- •1.
interface Config { [key: string]: string | number; } - •2.
const c: Config = { host: 'localhost', port: 3000 }; - •3. TypeScript allows any string key, but value must be string | number
- •4. Accessing:
c['host']→string | number - •5. Record shorthand:
type Config = Record<string, string | number>; - •6. Number keys:
{ [index: number]: string }— like arrays
Real-World Examples
- •HTTP headers:
Record<string, string> - •Translation map:
Record<string, string>— key=locale ID, value=translated text - •Score board:
Record<string, number>— key=player name, value=score - •CSS variables:
Record<string, string>— key=var name, value=colour
Key Facts
- •
Record<K, V>is shorthand for an index signature:{ [key in K]: V } - •Index signatures allow all string keys — TypeScript can't narrow a specific key's type
- •For known keys, use a proper interface or object type literal instead
- •When you access a Record value TypeScript returns T | undefined with noUncheckedIndexedAccess — use that config option for safer access
Watch Out!
Index signatures are looser than typed interfaces — TypeScript allows any string key so you lose specific property guarantees. If you know all the keys, use a proper typed interface: { name: string; age: number; } is safer than Record<string, string | number>.
Remember
{ [key: string]: ValueType } or Record<string, ValueType> — types objects with dynamic keys. Use when you genuinely don't know the keys ahead of time. Prefer explicit interfaces when keys are known.
What You Learned
- •Index signatures type dynamic-key objects:
{ [key: string]: Type }or Record - •Any string key is allowed; value type is enforced
- •Unlocks: HTTP headers, score maps, translation dictionaries, any key-value store
Key Facts
- →
Record<K, V>is shorthand for an index signature:{ [key in K]: V } - →Index signatures allow all string keys — TypeScript can't narrow a specific key's type
- →For known keys, use a proper interface or object type literal instead
- →When you access a Record value TypeScript returns T | undefined with noUncheckedIndexedAccess — use that config option for safer access
Real-World Examples
Remember
{ [key: string]: ValueType } or Record<string, ValueType> — types objects with dynamic keys. Use when you genuinely don't know the keys ahead of time. Prefer explicit interfaces when keys are known.
Quick Quiz
[key: string]: number means?