What a dictionary is
A dictionary stores key-value pairs: each key maps to one value, and you look a value up by its key instead of by a position number. In TypeScript the everyday dictionary is a plain object, written with curly braces. Keys and values are separated by a colon, and pairs are separated by commas.
const person = {"name": "Alice", "age": 25, "city": "NYC"};
console.log(person["name"]); // Alice
console.log(Object.keys(person).length); // 3
Here "name", "age" and "city" are keys, and "Alice", 25 and "NYC" are their values. Keys in an object are always strings (or symbols, which you won't need yet), even when you write a number: the key 1 becomes "1".
Typing a dictionary
When every value in a dictionary has the same type, say that with Record<string, number>. It describes an object whose keys are strings and whose values are numbers:
const scores: Record<string, number> = {"Alice": 95, "Bob": 87, "Charlie": 72};
The form { [key: string]: number } means the same thing and you will see it in other lessons. With the annotation, the compiler lets you add any string key whose value is a number, and it reports an error if you store a string instead. The annotation exists only for the compiler: it is erased when the code becomes JavaScript, and the program that runs is an ordinary object.
Adding and reading pairs
A dictionary can start empty and grow. Assigning to a key that isn't there adds a pair:
const scores: Record<string, number> = {};
scores["Alice"] = 95;
scores["Bob"] = 87;
console.log(scores); // { Alice: 95, Bob: 87 }
The annotation says what the dictionary is meant to hold, so the compiler can check every later assignment. A bare const scores = {} has the type {}, which describes no particular values, so it checks much less. Write the type down when you start from an empty object.
Reading a key that doesn't exist gives undefined, not an error, and the compiler still thinks the result is a number:
const scores: Record<string, number> = {"Alice": 95};
console.log(scores["Diana"]); // undefined
Objects and Map
TypeScript also has the built-in Map class, which is a dictionary with methods such as set, get and has, and a size property. A Map accepts keys of any type and remembers insertion order exactly, while an object only has string keys and lists whole-number keys first. Objects are shorter to write and are the most common choice, so this chapter uses them.
The lesson's exercise
The exercise asks you to create a dictionary named scores with three student scores. It has one step: declare scores as a Record<string, number> and give it the entries "Alice" mapped to 95, "Bob" to 87 and "Charlie" to 72.
- Choose the declaration. The name
scoresnever gets reassigned, soconstfits. - Add the type. After the name, write
: Record<string, number>. - Write the pairs inside curly braces, each as
"name": score, separated by commas.
const scores: Record<string, number> = {"Alice": 95, "Bob": 87, "Charlie": 72};
That is all the exercise needs. Printing scores would show { Alice: 95, Bob: 87, Charlie: 72 }.
Gotchas
- Quotes around keys.
{"Alice": 95}and{Alice: 95}are the same object. Quotes are required only when the key isn't a valid identifier, such as"first name". - Duplicate keys. A key can appear only once. If you write the same key twice in one literal, the compiler reports an error, and at run time the later value wins.
- Square brackets, not parentheses. You read a value with
scores["Alice"]. Writingscores("Alice")tries to call the object as a function. - Objects have no length property.
scores.lengthisundefined(and the compiler accepts it for aRecord). The count of pairs comes fromObject.keys(scores).length, which the later lessons cover. - Don't confuse curly braces. The same
{ }characters also mark code blocks. In a declaration after=, they create an object.
Key takeaways
- A dictionary maps keys to values, and in TypeScript it is usually an object written with
{ }. Record<string, number>types a dictionary with string keys and number values.- Pairs are written
key: valueand separated by commas. - A missing key reads as
undefined.