The Inventory

Now Kira's backpack. She carries three kinds of items: potions that heal, weapons that deal damage, and keys that open something. Each kind has different data, so the inventory is a job for a discriminated union from the lesson on modeling data. Each kind is an object type of its own with a kind tag, and Item is the union of them. Give each kind its own name, Potion, Weapon and Key: in the next step, you'll need the type Weapon by itself.

To describe an item, use a switch on the tag. In each case, TypeScript knows which kind of item it is, so in case "potion", you can use item.heal. And in default goes the exhaustiveness check with never from the lesson on modeling data: if a new kind is ever added and its case forgotten, TypeScript reports it right there. For example, spells:

type FireSpell = { kind: "fire"; name: string; damage: number };
type IceSpell = { kind: "ice"; name: string; turns: number };
type Spell = FireSpell | IceSpell;

function describeSpell(spell: Spell): string {
    switch (spell.kind) {
        case "fire":
            return `${spell.name} burns for ${spell.damage}`;
        case "ice":
            return `${spell.name} freezes for ${spell.turns} turns`;
        default:
            const unhandled: never = spell;
            return unhandled;
    }
}

const spells: Spell[] = [
    { kind: "fire", name: "Fireball", damage: 30 },
    { kind: "ice", name: "Frost Nova", turns: 2 },
];
for (const spell of spells) {
    console.log(`- ${describeSpell(spell)}`);
}

This prints:

- Fireball burns for 30
- Frost Nova freezes for 2 turns

Kira's items go into a new property of Hero, inventory: Item[]. In kira, it's an array of objects, and TypeScript checks each of them against its kind: a potion with damage instead of heal would be an error. The main program then prints the heading Inventory: and goes through the items with for...of.

Typical mistakes:

  • A capital letter in a case, case "Potion":. The tag is the exact text "potion", so TypeScript reports Type '"Potion"' is not comparable to type '"key" | "potion" | "weapon"'., and because of it, a few more errors below.
  • A forgotten case. Without case "key", the key ends up in default, and the never check names it: main.ts(36,19): error TS2322: Type 'Key' is not assignable to type 'never'.

Instructions

Under HeroClass, write the types Potion (kind: "potion", a name and heal, a number), Weapon (kind: "weapon", a name and damage, a number) and Key (kind: "key", a name and opens, a text), and type Item = Potion | Weapon | Key;. Add inventory: Item[] to Hero, and give Kira three items: { kind: "potion", name: "Healing Potion", heal: 20 }, { kind: "weapon", name: "Silver Sword", damage: 12 } and { kind: "key", name: "Old Key", opens: "the crypt" }.

Under describeHero, write a function describeItem(item: Item): string with a switch on item.kind and the never check in default. For the potion, it returns Healing Potion (heals 20), for the weapon Silver Sword (damage 12), and for the key Old Key (opens the crypt).

In the main program, under the line about Kira, print Inventory:, and then each item with - in front of it, in a for...of loop:

Kira the ranger, level 3, health 34/50, gold 120
Inventory:
- Healing Potion (heals 20)
- Silver Sword (damage 12)
- Old Key (opens the crypt)

Start programming for free

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

Or sign up with:

2/7