Array<T>
Вы уже давно пользуетесь обобщёнными типами, сами того не зная. Тип массива string[] — это короткая запись Array<string>: обобщённый тип Array<T> с аргументом типа string. Эти две строки означают одно и то же:
const names: string[] = ["Кира", "Бруно"];
const sameNames: Array<string> = ["Кира", "Бруно"];Аргументы обобщённых типов пишут в угловых скобках, как и у обобщённых функций. В аннотации типа их нужно писать всегда, ведь вывести их не из чего. Если забыть, TypeScript напомнит и покажет, как объявлен тип:
const loot: Array = ["Рубин", "Старый ключ"];TypeScript сообщает:
main.ts(1,13): error TS2314: Generic type 'Array<T>' requires 1 type argument(s).Так TypeScript описывает любой массив: Array<T>, где T — тип элементов, и методы массива тоже используют T. Поэтому push принимает только T, а find возвращает T | undefined: в уроке «Объединения и сужение типов» вы получали от него Item | undefined. map тоже обобщённый: он возвращает массив того, что возвращает ваша функция, поэтому prices.map(price => `Цена: ${price}`) — это string[]. В сообщениях об ошибках TypeScript записывает массивы коротко, например string[].
Когда понятнее Array<…>. В сундуке лежат названия предметов и монеты, поэтому его элементы — string | number:
const loot: string | number[] = ["Рубин", 25, "Старый ключ", 10];TypeScript сообщает:
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'.Аннотация string | number[] означает не то, чем кажется: [] относится только к number, поэтому это тип «строка или массив чисел». Строки с отступом показывают, как TypeScript пробует второй вариант и спотыкается на строках. Нужный вам тип — (string | number)[], со скобками, или, что читается легче, Array<string | number>.
Record тоже обобщённый. В уроке «Моделирование данных» вы использовали Record<Rarity, number>. Это обобщённый тип Record<K, V> с двумя параметрами типа: K для ключей и V для значений. В ошибках он выглядит как любой другой тип:
type Rarity = "common" | "rare" | "legendary";
const prices: Record<Rarity, number> = { common: 5, rare: 50 };TypeScript сообщает:
main.ts(2,7): error TS2741: Property 'legendary' is missing in type '{ common: number; rare: number; }' but required in type 'Record<Rarity, number>'.Обе записи массивов допустимы. Многие программисты пишут string[], когда тип элементов простой, и Array<…>, когда он длиннее, например объединение.
Задание
- 1
Исправьте аннотацию
loot: запишите её тип черезArray<…>, чтобы программа выводила:["Рубин", 25, "Старый ключ", 10] - 2
Напишите функцию
countCoins(things: Array<string | number>): number, которая складывает числа из массива и пропускает строки (сужайте тип черезtypeof). С её помощью выведите монеты в сундуке:Монеты: 35