Summary

In this lesson, you learned that:

  • A union type such as string | number allows a value of any of its types. Without a check, you may do only what works for all of them: reward.toUpperCase() on a string | number is an error.
  • A check narrows the type. Inside if (typeof reward === "string") { … }, reward is a string; in the else branch, and below an if that returns, it's a number. An array of a union needs parentheses: (number | string)[].
  • A literal union such as type HeroClass = "warrior" | "mage" | "ranger"; allows only these values. TypeScript reports typos in values, arguments and comparisons. A let with a text has the type string, so give it the type, or use const. Use literal unions instead of enum.
  • null and undefined belong to a type only if you write them there: Monster | null. Check such a value before you use it, for example with if (target === null) { return; }; otherwise, TypeScript reports 'target' is possibly 'null'.
  • find() returns the first matching element, or undefined when nothing matches. Its type is Item | undefined: handle both cases, and give a function that searches the return type Item | undefined.
  • hero.weapon?.name reads name only if hero.weapon exists, otherwise it gives undefined. value ?? "default" replaces null and undefined, but unlike ||, not 0 or "".
  • Array.isArray(loot) tells an array from a single value, for example in a string | string[]. Watch out for what works for both types, such as length and for...of.
  • unknown accepts every value, but allows nothing until you narrow it, for example with typeof. For data from outside, use it instead of any.
  • "heal" in item narrows a union of object types by a property. A type guard, function isPotion(item: Item): item is Potion, puts such a check into a function. TypeScript trusts it, so the check must be right.

In the next lesson, Modeling Data, you'll learn the most common way to model data with unions in TypeScript: discriminated unions, where a property such as kind says what each object is. You'll also learn JavaScript's switch, and how TypeScript makes sure that you haven't forgotten a case.

Instructions

Let's practice. The tavern in the editor has a quest board. Each quest has a region, a reward (gold or an item), and sometimes a hero who helps with it. Run the program: TypeScript finds a mistake in the data. Fix it.

Write a function formatReward with a parameter reward of the type number | string and the return type string. For a number, it returns, for example, 10 gold; for a text, the text with the in front of it, for example the Silver Sword.

Write a function describeQuest with a parameter title (a text). It finds the quest with this title on the board and returns a description such as Rats in the Mine (mines): 10 gold, helper: nobody: use formatReward, and ?? for a quest without a helper. When no quest has this title, it returns, for example, No quest called Dragon Hunt. Print the descriptions of "The Troll Bridge", "Rats in the Mine" and "Dragon Hunt". The program then prints:

The Troll Bridge (mountains): the Silver Sword, helper: Bruno
Rats in the Mine (mines): 10 gold, helper: nobody
No quest called Dragon Hunt

Start programming for free

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

Or sign up with:

10/10