Summary
In this lesson, you learned that:
- A union type such as
string | numberallows a value of any of its types. Without a check, you may do only what works for all of them:reward.toUpperCase()on astring | numberis an error. - A check narrows the type. Inside
if (typeof reward === "string") { … },rewardis astring; in theelsebranch, and below anifthat returns, it's anumber. 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. Aletwith a text has the typestring, so give it the type, or useconst. Use literal unions instead ofenum. nullandundefinedbelong to a type only if you write them there:Monster | null. Check such a value before you use it, for example withif (target === null) { return; }; otherwise, TypeScript reports'target' is possibly 'null'.find()returns the first matching element, orundefinedwhen nothing matches. Its type isItem | undefined: handle both cases, and give a function that searches the return typeItem | undefined.hero.weapon?.namereadsnameonly ifhero.weaponexists, otherwise it givesundefined.value ?? "default"replacesnullandundefined, but unlike||, not0or"".Array.isArray(loot)tells an array from a single value, for example in astring | string[]. Watch out for what works for both types, such aslengthandfor...of.unknownaccepts every value, but allows nothing until you narrow it, for example withtypeof. For data from outside, use it instead ofany."heal" in itemnarrows 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 HuntStart programming for free
10/10