Параметры без типа
Компилятор выводит тип из значения, которое видит в коде. А какое значение он видит у параметра функции без значения по умолчанию? Никакого. Параметр похож на пустую банку, которую поставили на полку заранее. Что в неё насыплют, решат те, кто будет вызывать функцию, и каждый может насыпать своё.
Перенесём в TypeScript обычную функцию из JavaScript:
function add(a, b) { // ✗
return a + b;
}error TS7006: Parameter 'a' implicitly has an 'any' type.Сообщение значит: «параметр a неявно получает тип any». Такую же ошибку tsc выдаёт и для b. В JavaScript эта функция работает с чем угодно: add(2, 3) даёт 5, а add("2", 3) — строку "23". TypeScript не знает, что задумал автор, и не берётся угадывать.
Почему тип не выводится из вызовов
Может показаться, что компилятор мог бы посмотреть, как функцию вызывают, и вывести тип параметра оттуда. Он так не делает, и на это есть причины:
- функцию вызывают из разных мест и даже из других файлов, и в каждом вызове может быть своё значение;
- вызовов может ещё не быть: функцию часто пишут раньше, чем её используют;
- тип параметра — договор, который пишет автор функции, а не тот, кто её вызывает.
Поэтому параметр без аннотации получает тип any — тот самый «что угодно», который вы уже видели у переменной без значения. С any проверок нет: a и b можно складывать с чем угодно и вызывать у них любые методы, а ошибки переедут обратно на время запуска.
Проверка noImplicitAny
Строгий режим, который в TypeScript 7 включён по умолчанию, состоит из нескольких проверок. Одна из них — noImplicitAny, «никакого неявного any»: она запрещает any, который появился сам, без вашего решения. Именно эта проверка и выдаёт ошибку TS7006.
Исправление — написать типы параметров:
function add(a: number, b: number) {
return a + b;
}
console.log(add(2, 3)); // 5Тип результата здесь писать не нужно: из a + b двух чисел TypeScript сам выведет number. А вызов add("2", 3) теперь даст ошибку TS2345 ещё до запуска программы.
Где писать типы
Этот вопрос часто задают на собеседовании: «Когда писать тип явно, а когда положиться на вывод?» Ответ складывается из того, что вы уже знаете:
- у параметров функции тип пишут — выводу нечего читать;
- у переменной без начального значения — тоже;
- у переменной со значением тип не пишут — он выведется из значения;
- тип результата выведется из
return, но его пишут, когда хотят закрепить: тогда ошибку в теле функции видно сразу уreturn.
Частая ошибка
Написать тип результата и решить, что параметры теперь понятны:
function add(a, b): number { // ✗
return a + b;
}error TS7006: Parameter 'a' implicitly has an 'any' type.Аннотация результата не подсказывает типы параметров: TypeScript не выводит их ни из return, ни из вызовов. Тип нужен каждому параметру: function add(a: number, b: number): number.
Главное
- Параметру без значения по умолчанию не из чего вывести тип: без аннотации он неявно получает
any. - В строгом режиме проверка
noImplicitAnyпревращает такой параметр в ошибкуTS7006. - С
anyпроверок нет, и ошибки переезжают на время запуска. - Типы параметров пишут сами, а тип переменной со значением выводит компилятор.