Summary

In this lesson, you learned that:

  • A class is a template for objects: class Monster { name: string = "Goblin"; }. new Monster() creates an instance, which prints as Monster { name: "Goblin" }. The class's name is also a type: function hit(monster: Monster).
  • Every field needs a value, an initial value or one from the constructor; otherwise, you get TS2564.
  • The constructor runs at new and gets its arguments: constructor(name: string) { this.name = name; }. Inside it, this is the new object. The short form constructor(public name: string) isn't allowed here (TS1294).
  • Methods are functions in a class: describe(): string { return this.name; }, called as kira.describe(). Inside a method, this is the object in front of the dot. Without this., TypeScript reports TS2663.
  • A private field can be used only inside the class (TS2341 elsewhere); methods are the way in. Without private, a member is public. JavaScript's own private fields start with #.
  • A readonly field gets its value only as its initial value or in the constructor (TS2540 elsewhere).
  • class Wizard implements Character makes TypeScript check that the class has everything the interface asks for (TS2420). TypeScript compares shapes, so any object of the right shape fits the interface.
  • class Boss extends Monster inherits the fields and methods of Monster. Its constructor must call super(…) first (TS2377). A Boss fits wherever a Monster is expected.
  • A derived class can override a method: override describe(): string. override makes TypeScript check that the parent has the method (TS4117), and super.describe() calls the parent's version.

In the next lesson, Utility Types, you'll build new types out of the ones you have: a hero whose properties are all optional, a hero without its id, and more.

But first, put this lesson together. Kira's bag holds different things that can all be used. The interface for them is in the editor.

Instructions

Write a class Potion that implements Usable. It has a read-only field name and a private field doses (a number), both set by the constructor. Its method use() returns `${name} is empty` when no doses are left. Otherwise, it takes one dose away and returns `${name}: ${doses} left`, for example Healing Potion: 1 left.

Create const potion = new Potion("Healing Potion", 2); and use the potion three times, printing what use() returns each time:

Healing Potion: 1 left
Healing Potion: 0 left
Healing Potion is empty

Write a second class, Scroll, that also implements Usable. It has a read-only name and a read-only spell, both set by the constructor, and its use() returns `${name}: you cast ${spell}`. Then put a new potion and a scroll into a bag, const bag: Usable[] = [new Potion("Mana Potion", 1), new Scroll("Scroll of Light", "Light")];, and use everything in the bag in a for...of loop, printing the results. The program prints:

Healing Potion is empty
Mana Potion: 0 left
Scroll of Light: you cast Light

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

9/9