TypeScript: Функции как параметры
В TypeScript используется несколько способов типизировать функции, которые передаются как параметры. В этом уроке мы научимся работать с ними.
Как типизировать функции, которые передаются как параметры
Самый простой способ типизировать функции как параметры — использовать тип Function
. Он описывает функцию JavaScript со всеми ее особенностями, включая свойства bind
, call
и apply
.
Опишем входной параметр callback
функции process
:
function process(callback: Function) {
const value = callback();
// ...
}
Function
отключает проверку типов для вызываемой функции. В итоге количество и тип входных аргументов не проверяются, а результатом работы такой функции будет any
. Это может привести к логическим ошибкам и неожиданному поведению:
process(Math.round); // ?
Данный пример сработает, хотя поведение вряд ли будет ожидаемым, так как Math.round
вызовется без аргументов и вернет NaN
. Поэтому мы рекомендуем избегать использования Function
.
Другой способ описывать функции — использовать стрелочную функцию с указанием входных и выходных типов:
function process(callback: () => string) {
// value имеет тип string
const value = callback();
// ...
}
process(Math.round);
// Argument of type '(x: number) => number' is not
// assignable to parameter of type '() => string'.
Определение стрелочной функции похоже на настоящую, но тут важно не перепутать. Здесь мы видим именно описание типа, а не определение функции.
Рассмотрим еще несколько примеров для закрепления:
function process(callback: () => number)
function process(callback: () => string[])
function process(callback: () => { firstName: string; })
Параметры синтаксически указываются так же, как и для стрелочных функций:
function process(callback: (n: number) => string) {
const value = callback(10);
// ...
}
Здесь мы определили тип callback
функцией с параметром n
с типом number
и возвращаемое значение string
.
Если определение функции встречается часто, то для него можно создать псевдоним:
type myFunction = (n: number) => string;
function process(callback: myFunction) {
const value = callback(10);
// ...
}
Такая запись упрощает чтение кода и позволяет избежать дублирования.
Задание
Реализуйте функцию filter()
, которая принимает на вход массив чисел и предикат. Последний будет использоваться для проверки каждого числа на соответствие требованиям:
const numbers = [1, -5, 2, 3, 4, 133];
filter(numbers, (n) => n > 3); // [4, 133]
filter(numbers, (n) => n % 2 == 0); // [2, 4]
Параметры функции:
- Массив чисел
- Анонимная функция, которая принимает на вход число и возвращает логическое значение
Упражнение не проходит проверку — что делать? 😶
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет 🤨
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя 🤔
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно 🙄
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.