Бесплатный курс по TypeScript. Зарегистрируйтесь для отслеживания прогресса →

TypeScript: Функции как параметры

В TypeScript используется несколько способов типизировать функции передаваемые как параметры. Самый простой - использовать тип Function. Он описывает собой функцию JavaScript со всеми ее особенностями включая свойства bind, call и apply.

function process(callback: Function) {
  const value = callback();
  // ...
}

Несмотря на простоту и удобство, Function отключает проверку типов для вызываемой функции. Никак не проверяется количество и тип входных аргументов, а результатом работы такой функции будет any. В общем случае Function стоит избегать.

// Сработает, хотя по смыслу не должно
// Внутри Math.round вызовется без аргументов
process(Math.round);

Другой способ описывать функции - использовать стрелочную функцию с указанием входных и выходных типов.

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);
  // ...
}

Если определение функции встречается часто, то для него можно создать псевдоним:

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); // [4, 133]

Параметры функции:

  1. Массив чисел
  2. Анонимная функция принимающая на вход число и возвращающая логическое значение
Упражнение не проходит проверку — что делать? 😶

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

  • Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет 🤨

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Мой код отличается от решения учителя 🤔

Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.

В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Прочитал урок — ничего не понятно 🙄

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.

Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Если вы столкнулись с трудностями и не знаете, что делать, задайте вопрос в нашем большом и дружном сообществе