Array<T>
You've been using generic types for a while without knowing it. The array type string[] is a short way of writing Array<string>: the generic type Array<T> with the type argument string. These two lines mean exactly the same:
const names: string[] = ["Kira", "Bruno"];
const sameNames: Array<string> = ["Kira", "Bruno"];Generic types get their type arguments in angle brackets, like generic functions. In a type annotation, you always write them, since there's nothing to infer them from. If you forget, TypeScript reminds you, and shows how the type is declared:
const loot: Array = ["Ruby", "Old Key"];TypeScript reports:
main.ts(1,13): error TS2314: Generic type 'Array<T>' requires 1 type argument(s).That's how TypeScript describes every array: Array<T>, where T is the type of the elements, and the array's methods use T too. That's why push accepts only a T, and why find returns a T | undefined: in lesson 5, you got an Item | undefined from it. map is generic as well: it returns an array of whatever your function returns, so prices.map(price => `${price} gold`) is a string[]. In error messages, TypeScript writes arrays the short way, for example string[].
When Array<…> is clearer. A chest holds item names and coins, so its elements are string | number:
const loot: string | number[] = ["Ruby", 25, "Old Key", 10];TypeScript reports:
main.ts(1,7): error TS2322: Type '(string | number)[]' is not assignable to type 'string | number[]'.
Type '(string | number)[]' is not assignable to type 'number[]'.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.The annotation string | number[] doesn't mean what it looks like: the [] belongs only to number, so the type is “a text, or an array of numbers”. The indented lines show TypeScript trying the second option and failing on the texts. The type you want is (string | number)[], with parentheses, or, easier to read, Array<string | number>.
Record is generic too. In lesson 6, you used Record<Rarity, number>. That's the generic type Record<K, V> with two type parameters: K for the keys and V for the values. In errors, it shows up like any other type:
type Rarity = "common" | "rare" | "legendary";
const prices: Record<Rarity, number> = { common: 5, rare: 50 };TypeScript reports:
main.ts(2,7): error TS2741: Property 'legendary' is missing in type '{ common: number; rare: number; }' but required in type 'Record<Rarity, number>'.Both ways of writing arrays are fine. Many programmers write string[] when the element type is simple, and Array<…> when it's longer, like a union.
Instructions
Fix the annotation of loot: write its type with Array<…>, so that the program prints:
["Ruby", 25, "Old Key", 10]Write a function countCoins(things: Array<string | number>): number that adds up the numbers in the array and skips the texts (narrow with typeof). Print the coins in the chest with it:
Coins: 35Start programming for free
4/9