TypeScript Tutorial · TypeScript Basics · Lesson 5 of 25
TypeScript Index Signatures and Records
Type objects used as dictionaries with index signatures and Record.
Dictionaries
When an object's keys aren't known in advance — a lookup table, word counts, a cache — describe it with an index signature or Record:
const wordCounts: { [word: string]: number } = {};
for (const w of "the cat and the hat".split(" ")) {
wordCounts[w] = (wordCounts[w] ?? 0) + 1;
}
console.log(wordCounts);
const cache: Record<string, string> = {};
cache["/home"] = "<html>...</html>";
console.log(Object.keys(cache));
Output
{ the: 2, cat: 1, and: 1, hat: 1 }
[ '/home' ]Record<K, V> is shorthand for { [key in K]: V }. With a union of literal keys, it forces you to provide every key:
type Env = "dev" | "staging" | "prod";
const apiUrl: Record<Env, string> = {
dev: "http://localhost:8000",
staging: "https://staging.example.com",
prod: "https://api.example.com",
};
// @ts-expect-error — Property 'prod' is missing in type.
const incomplete: Record<Env, string> = { dev: "x", staging: "y" };
console.log(apiUrl.prod, Object.keys(incomplete).length);
Output
https://api.example.com 2
For dictionaries that change at runtime, a Map<K, V> is often the better choice.
Test yourself
What does Record<"a" | "b", number> require?
An object with key a or bAn object with both keys a and b, each a numberAn array of numbersA Map
Show answer
Answer: An object with both keys a and b, each a number