Аргументы типа
Когда вы вызываете first(names), вы не указываете, чем является T: TypeScript выводит это из аргумента. Это снова вывод типов, на этот раз для параметра типа. Тип можно написать и самому — в угловых скобках между именем функции и круглыми скобками:
const leader = first<string>(names);Тип в угловых скобках — это аргумент типа. Он подставляется в параметр типа T, так же как аргумент names подставляется в параметр items. Здесь он ничего не меняет, ведь TypeScript и сам выбрал бы string. Но теперь TypeScript проверяет аргументы по тому типу, который вы написали:
function first<T>(items: T[]): T | undefined {
return items[0];
}
const potions = ["Лечебное зелье", "Зелье маны"];
console.log(first<string>(potions));
console.log(first<number>(potions));TypeScript сообщает:
main.ts(6,27): error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'number[]'.
Type 'string' is not assignable to type 'number'.Если T — это number, параметр items: T[] становится number[], и массив строк не подходит. Вторая строка с отступом объясняет почему: строка — не число. В длинных сообщениях часто бывают такие строки; читайте их сверху вниз, каждая следующая даёт больше подробностей.
Параметр типа может встречаться в нескольких местах, и везде он должен быть одним и тем же:
function pairUp<T>(first: T, second: T): T[] {
return [first, second];
}
console.log(pairUp("Кира", "Бруно"));
console.log(pairUp("Кира", 5));TypeScript сообщает:
main.ts(6,28): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.По первому аргументу, "Кира", TypeScript решил, что T — это string, поэтому и второй аргумент должен быть строкой.
У функции может быть и несколько параметров типа, через запятую. Эта функция делает кортеж (урок 2) из любых двух значений:
function pair<A, B>(first: A, second: B): [A, B] {
return [first, second];
}
const potionCount = pair("Лечебное зелье", 3);
console.log(potionCount);Программа выводит:
["Лечебное зелье", 3]Здесь A — это string, а B — это number, поэтому potionCount имеет тип [string, number].
Когда писать аргументы типа. Обычно не нужно: пусть TypeScript выводит их сам. Они нужны, когда TypeScript вывел бы слишком узкий тип. Эта функция заполняет три ячейки рюкзака одним значением, а у Киры сначала все ячейки пусты — null:
function fill<T>(value: T): T[] {
return [value, value, value];
}
const slots = fill(null);
slots[1] = "Щит";
console.log(slots);TypeScript сообщает:
main.ts(6,1): error TS2322: Type '"Щит"' is not assignable to type 'null'.Из null TypeScript вывел, что T — это null, поэтому slots — массив, в котором могут лежать только null. Напишите нужный тип как аргумент типа, const slots = fill<string | null>(null);, и в ячейках смогут лежать строки или null. Тогда программа выведет:
[null, "Щит", null]Задание
- 1
Напишите обобщённую функцию
repeat<T>(value: T, times: number): T[], которая возвращает новый массив, гдеvalueповторяетсяtimesраз. Начните с пустого массива,const result: T[] = [];, и добавляйте в него значение черезpushв циклеfor. - 2
Под функцией создайте
const arrows = repeat("Стрела", 3);и выведитеarrows:["Стрела", "Стрела", "Стрела"] - 3
В рюкзаке Киры четыре ячейки, сначала пустые. Создайте их с помощью
repeatв переменнойslots:nullчетыре раза, с аргументом типаstring | null, чтобы позже в ячейки можно было положить строки. Затем положите"Меч"в первую ячейку (индекс0) и выведитеslots. Программа выведет:["Стрела", "Стрела", "Стрела"] ["Меч", null, null, null]