Exercise 9 of 10 · Object types
The Departure Board
What you will make
A station departure board showing the destination, platform and wait for every train, built from objects that all match one Train type.
The one new idea: an object type lists the properties an object must have, and the compiler checks every object against it
Real data comes in records: a customer with a name and an email, an order with items and a total, a train with a destination and a platform. An object type writes the shape of a record down once, and from then on the compiler refuses any record with a piece missing, misspelt or of the wrong kind.
Go straight to the code ↓An object keeps related values together
A train on a departure board is not one value but several that belong together: where it goes, which platform, how long until it leaves. An object holds them as named properties:
const ferry = { destination: "Skye", cars: 32 };
console.log(ferry.destination);
console.log(ferry.cars + 1);Skye
33Curly braces make the object. Inside them, each property is a name, a colon and a value, with commas between
the properties. A dot reads a property back out, so ferry.destination is "Skye".
A type describes the shape
An object type writes that shape down and gives it a name:
type Ferry = {
destination: string;
cars: number;
};
const morning: Ferry = { destination: "Skye", cars: 32 };
console.log(morning.destination, "with", morning.cars, "cars");Skye with 32 carstype Ferry = { ... }; makes a new type called Ferry. Each line inside it lists one property: its name, a
colon, its type and a semicolon. The type prints nothing and creates no ferry. It is a description the compiler
holds objects to, and const morning: Ferry is a type annotation like : number, promising that morning has
that shape.
Type names start with a capital letter by habit, which keeps Ferry, the description, apart from morning, an
actual ferry.
What the compiler checks
Leave a property out:
type Ferry = {
destination: string;
cars: number;
};
const evening: Ferry = { destination: "Mull" };
console.log(evening.destination);main.ts(6,7): error TS2741: Property 'cars' is missing in type '{ destination: string; }' but required in type 'Ferry'.The part in the middle, { destination: string; }, is the compiler describing the object you actually wrote. It
sets that against Ferry, the shape you promised, and cars is the difference.
Misspell a property, and the compiler suggests the one you meant:
type Ferry = {
destination: string;
cars: number;
};
const evening: Ferry = { destination: "Mull", crs: 12 };
console.log(evening.destination);main.ts(6,47): error TS2561: Object literal may only specify known properties, but 'crs' does not exist in type 'Ferry'. Did you mean to write 'cars'?An object literal is an object written out in braces, like the one on that line.
An array of objects
Train[] is an array of trains, the way string[] was an array of strings. Every object in it is checked
against Train, and a for...of loop hands them over one at a time already known to be trains, which is why
each one can be handed to departure, whose parameter says it takes a Train.
Your turn
The editor holds a departure board: a Train type, a departure function that builds one row from a train, and
three trains in an array. Press Run first. Nothing prints, and the compiler reports:
main.ts(20,3): error TS2741: Property 'platform' is missing in type '{ destination: string; minutes: number; }' but required in type 'Train'.Line 20 is the Dover train. Give it the property it is missing; the comment at the top of the program says which platform Dover leaves from.
If something goes wrong
If the message changes to Type 'string' is not assignable to type 'number'., the platform has quotes around it.
A platform here is a number, as the type says.
If the compiler asks Did you mean to write 'platform'?, the property name is misspelt. Property names must
match the type letter for letter.
If you deleted platform from the type instead, several new messages arrive at once: the other two trains still
have a platform the type no longer knows about, and the departure function still reads train.platform. The
type describes what a train is. Fix the data to fit it, not the other way round.
Write your code
Runs in your browser. Press Run (or Ctrl/Cmd+Enter) and the output is checked for you.
Press Esc then Tab to move keyboard focus out of the code editor.
Output will appear here after you run your code.The runtime is starting in the background. You can type now — it will be ready before you are.
The answer appears here once you have run your code at least once.
Things that often go wrong here
- Giving the platform in quotes
- The Train type says a platform is a number, and quotes make text, so the compiler refuses the Dover line with Type 'string' is not assignable to type 'number'. Take the quotes off the 2.
- Misspelling the new property
- Property names must match the type letter for letter. Written as platfrom, the compiler both refuses the unknown name and suggests the right one: Object literal may only specify known properties, but 'platfrom' does not exist in type 'Train'. Did you mean to write 'platform'?
- Deleting platform from the type instead of adding it to Dover
- The first message goes and new ones take its place: the other two trains still have a platform the type no longer knows about, and the departure function still reads train.platform, which now gives Property 'platform' does not exist on type 'Train'. The type describes what a train is; change the data to fit it.
- Writing an equals sign inside the object
- Inside the braces of an object, each property is a name, a colon and a value. With platform = 2 the compiler stops and asks whether you meant a colon, before anything prints.
Want a blank editor instead? Open the TypeScript playground.