One or Many: Array.isArray
Some functions are handier when they accept one value or several. A chest may hold one item or a list of items, and you'd like to call the same function for both: openChest("Silver Sword") as well as openChest(["Healing Potion", "Rope"]). The type of such a parameter is string | string[]: a text, or an array of texts.
Compare it with the array type from the exercise about typeof: string | string[] is “one text, or an array of texts”, while (string | number)[] is “an array whose elements are texts or numbers”. The parentheses decide what the [] belongs to.
How do you find out which one you got? typeof can't recognize an array: for an array, it gives "object", just like for any object. (Here, typeof loot === "string" would work too, because the only other choice is an array.) JavaScript has a function made for arrays: Array.isArray(value) returns true when the value is an array, and false otherwise. TypeScript understands it and narrows the type:
function openChest(loot: string | string[]): void {
if (Array.isArray(loot)) {
for (const item of loot) {
console.log(`You find: ${item}`);
}
} else {
console.log(`You find: ${loot}`);
}
}
openChest(["Healing Potion", "Rope"]);
openChest("Silver Sword");This prints:
You find: Healing Potion
You find: Rope
You find: Silver SwordInside the if, loot is a string[]; in the else branch, a string. Without the check, TypeScript allows only what works for both, and array methods don't:
function openChest(loot: string | string[]): void {
loot.push("Rope");
}main.ts(2,10): error TS2339: Property 'push' does not exist on type 'string | string[]'.
Property 'push' does not exist on type 'string'.But be careful: some things work for both types, and then TypeScript doesn't complain, even when the result isn't what you meant. Both texts and arrays have length, and you can go through both with for...of. Without the check, openChest("Rope") would go through the letters of the text:
function openChest(loot: string | string[]): void {
for (const item of loot) {
console.log(`You find: ${item}`);
}
}
openChest("Rope");This prints:
You find: R
You find: o
You find: p
You find: eTypeScript checks that what you do is allowed for the types. It can't check that it's what you wanted.
Instructions
The program prints 3 and 12. TypeScript allows loot.length, because texts have a length too, but for "Silver Sword", it's the number of characters. Fix countItems with Array.isArray, so that a single item counts as 1. The program then prints:
3
1Below, write a function showLoot with a parameter loot of the type string | string[]. It prints every item on its own line, with - in front of it.
Call showLoot for the same two chests. The program then prints:
3
1
- Healing Potion
- Old Key
- Rope
- Silver SwordStart programming for free
7/10