Interfaces
There's a second way to describe the shape of an object: an interface.
interface Monster {
name: string;
health: number;
}It means the same as type Monster = { name: string; health: number };. You use Monster in annotations the same way, and the error messages are the same. It's only written differently: after interface comes the name and right after it the curly braces, without =. People usually write each property on its own line.
What interfaces are especially good at is extending. A boss is a monster with something extra, the phase of the fight. With extends, the interface Boss gets every property of Monster (name and health) and adds its own:
interface Monster {
name: string;
health: number;
}
interface Boss extends Monster {
phase: number;
}
const wolf: Monster = { name: "wolf", health: 30 };
const dragon: Boss = { name: "dragon", health: 300, phase: 1 };
function describe(monster: Monster): string {
return `${monster.name}: ${monster.health} health`;
}
console.log(describe(wolf));
console.log(describe(dragon));
console.log(dragon);This prints:
wolf: 30 health
dragon: 300 health
{ name: "dragon", health: 300, phase: 1 }You write the shared properties only once. And when Monster gets a new property, Boss gets it too.
Notice that describe takes a Monster, and you can pass it the dragon. A boss has everything a monster has, so it is a monster too. The other way round, it doesn't work: a monster isn't a boss, because it has no phase:
interface Monster {
name: string;
health: number;
}
interface Boss extends Monster {
phase: number;
}
function describeBoss(boss: Boss): string {
return `${boss.name}, phase ${boss.phase}`;
}
const wolf: Monster = { name: "wolf", health: 30 };
console.log(describeBoss(wolf));main.ts(15,26): error TS2741: Property 'phase' is missing in type 'Monster' but required in type 'Boss'.type or interface? For the shape of an object, both work, and you'll see both in real code. Many teams use interface for objects and type for everything else, such as the function types from the previous lesson, or the unions in the next lesson, which can't be written as an interface at all. This course uses both.
Typical mistakes:
- An
=after the name, as withtype:
interface Monster = {
name: string;
health: number;
}main.ts(1,19): error TS1005: '{' expected.- A boss object without the extra property:
Property 'phase' is missing in type '{ name: string; health: number; }' but required in type 'Boss'.
Instructions
Rewrite Character as an interface, with each property on its own line.
Create an interface Hero that extends Character and adds two properties: heroClass of type string and gold of type number. Then, below the innkeeper, create kira of type Hero: Kira, level 3, a "ranger" with 120 gold.
Replace the console.log line with a function introduce that takes a Character and returns its text, such as Ema, level 1. Print introduce(innkeeper) and introduce(kira): Kira is a hero, and so also a character. The program prints:
Ema, level 1
Kira, level 3Start programming for free
6/10