CHAPTER 2 · 8 lessons · 104 exercises

Describe the shape of an object

Write down which named values an object holds. Give that shape a name with `type` and `interface`.

In chapter 1 you put types on single values and on arrays of one kind of thing. What this chapter is about is objects.

An object was a container that can hold several named values. Name and age for a person, title and price for a product. It is the { name: "Yui", age: 20 } you have been writing since the JavaScript course.

Remember how it differs from an array. An array is a container where "things of the same kind line up", and its contents had one type. An object is a container where "things of different kinds gather up, each with a name". So the type is written differently too. Where an array needed only the type of one item, an object is written by lining up the name and type of each property.

The thing that bites hardest is mistyping a name. You mean to write age and you write aeg. JavaScript will not tell you. Read it back and you get undefined, it slips into a sum and becomes NaN, and you finally notice several lines further down. With the type written, it stops you on the line where you mistyped. This is the part of the chapter I most want you to feel.

And an object type is something you end up writing again and again. The same shape turns up on a function parameter, on a return type, inside an array. So you give the shape a name. There are two ways to do it — put another name on it with type, or declare it with interface. They can do very nearly the same things. We will talk about when to reach for which, too.

Beyond that, real data has "fields that are sometimes there and sometimes not" — a nickname some people have registered and others have not. Put a ? on a property like that to make it optional. The other way round, put readonly on something you do not want changed after it is made. Both cost you one character and take away room for things to break later.

Next comes an array of objects. A register, a product list — real data nearly always has this shape. Once you can write Item[], pulling out one row at a time with for...of still knows the type of what is inside, so property-name completion and typo detection both keep working.

At the end of the chapter there are three things that go a step further.

The first is how TypeScript decides whether types fit. It is not by name, as it happens. If the shape is the same, it fits. So even a plain object that never claimed to be a Person can be handed to something wanting a Person, so long as it has the properties needed. Once you see this, you can explain to yourself why one thing goes through and another does not.

The second is how to write an object whose keys are not known in advance. Like a score per person, where the keys cannot be known until it runs. For that, instead of lining up property names, you can write "keys are strings, values are numbers" in one go.

The third is a readonly array. What you did to a property you can do to an array. Declare it read-only and an accidental push gets stopped where it happens.

By the end of this chapter you will be able to leave "this data has this shape" written in the code. A type is a blueprint for data. Once you can write that, you can also read someone else's type definitions and understand what data their app works with.

Lessons in this chapter

Type an object

  1. 05Adding types to objectsWrite down which named values go inside an object, and catch a typo the moment you make it.Go to the exercises

Give the shape a name

  1. 06Giving a type a nameWrite type Person = { ... }; to name a shape, so you never write the same type twice.Go to the exercises
  2. 07Declaring a shape with interfaceLearn interface Person { ... }, the other way of declaring the shape of an object.Go to the exercises

Pin down the details

  1. 08Fields you can leave out, and fields you never changeDeclare "this might not be there" with ?, and "do not change this later" with readonly.Go to the exercises
  2. 09Arrays of objectsWrite Item[] and handle data that is a row of objects of the same shape, all by the type.Go to the exercises

Go one step further

  1. 10Same shape, and it goes throughWhether a type fits is decided by the shape, not the name. An object that never claimed to be a Person goes through.Go to the exercises
  2. 11When you do not know the names of the keysWrite { [key: string]: number } to type an object whose keys you cannot know until it runs.Go to the exercises
  3. 12Arrays you cannot changeWrite readonly string[] to declare a read-only array. Changing it by accident gets stopped by the type.Go to the exercises

Next up is “Narrow what a value can be”. Allow more than one type, like a string or a number, then check it before you use it and narrow it down.