🇬🇧 Limited Time — UK Only·🎓 Free Learning for 1 Month·🤖 Free AI Training Included·📚 4,000+ Lessons · 35,000+ Quizzes·🏆 GCSE Mocks · Olympiad Papers·⚡ Selected Students Only · Limited Places·🎁 Free Value Worth £2,000·🇬🇧 Limited Time — UK Only·🎓 Free Learning for 1 Month·🤖 Free AI Training Included·📚 4,000+ Lessons · 35,000+ Quizzes·🏆 GCSE Mocks · Olympiad Papers·⚡ Selected Students Only · Limited Places·🎁 Free Value Worth £2,000·🇬🇧 Limited Time — UK Only·🎓 Free Learning for 1 Month·🤖 Free AI Training Included·📚 4,000+ Lessons · 35,000+ Quizzes·🏆 GCSE Mocks · Olympiad Papers·⚡ Selected Students Only · Limited Places·🎁 Free Value Worth £2,000·
📘 TypeScript

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…

8 min 10 XP Lesson 14 of 21
Index signatures
🌐

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

• HTTP headers: <code>Record&lt;string, string&gt;</code> • Translation map: <code>Record&lt;string, string&gt;</code> — key=locale ID, value=translated text • Score board: <code>Record&lt;string, number&gt;</code> — key=player name, value=score • CSS variables: <code>Record&lt;string, string&gt;</code> — key=var name, value=colour

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

1 / 2

[key: string]: number means?