Вывод типов
В прошлом уроке вы подписывали каждую банку сами. Но часто содержимое видно и без наклейки. Если в банку насыпали гречку, подписать её может помощник: он видит, что внутри, и пишет «Гречка» за вас.
В TypeScript такой помощник — компилятор. Запись let count: number = 0 говорит «число» дважды: один раз в аннотации и второй раз нулём справа. Компилятору хватает нуля. Когда компилятор сам определяет тип по коду — по начальному значению переменной или по тому, что возвращает функция, — это называется выводом типов.
Тип из начального значения
let count = 0;
let title = "Отчёт";
count = count + 1;
title = title + " за май";
console.log(count, title); // 1 Отчёт за майАннотаций здесь нет, но типы у переменных есть. Давайте разберём пример по строкам:
let count = 0;— справа число, и TypeScript выводит дляcountтипnumber.let title = "Отчёт";— справа строка, иtitleполучает типstring.count = count + 1;кладёт число вnumber— проверка проходит.title = title + " за май";кладёт строку вstring— тоже проходит.console.logпечатает1 Отчёт за май.
Выведенный тип проверяется так же строго, как написанный. Строка count = "два"; дала бы здесь ту же ошибку TS2322, что и с аннотацией let count: number = 0.
Как увидеть выведенный тип
Помощник пишет наклейку, но в коде её не видно. Чтобы её прочитать, наведите курсор на имя в редакторе — в VS Code или в TypeScript Playground. Над count появится подсказка let count: number, над title — let title: string.
Подсказкой удобно проверять себя. Прежде чем гадать, какой тип у переменной, наведите на неё курсор: подсказка покажет то, что знает компилятор.
Тип результата функции
Помощник читает не только начальные значения, но и return:
function withDelivery(price: number) {
return price + 300;
}
const total = withDelivery(1200);
console.log(total); // 1500У функции нет аннотации ): number, но TypeScript видит выражение после return: price + 300 — это число плюс число, значит, результат тоже число. Поэтому и total получает тип number.
Тип параметра price здесь написан явно. У параметра без значения по умолчанию нет начального значения, и помощнику нечего прочитать.
Переменная без значения
Иногда переменную объявляют без начального значения, а заполняют позже:
let total;
total = 1200;
total = "бесплатно";
console.log(total); // бесплатноЗдесь читать нечего, и подсказка над total в первой строке покажет let total: any. any — особый тип «что угодно»: в такую переменную можно записать и число, и строку, и tsc промолчит.
Наклейки на такой банке нет: помощник только запоминает, что в неё насыпали последним. Поэтому над total в строке с console.log подсказка покажет let total: string, а записать в total по-прежнему можно что угодно.
Если переменной нужен тип, напишите его сами: с объявлением let total: number; строка total = "бесплатно"; даст ошибку TS2322.
Что такое вывод типов, часто спрашивают на собеседовании. Короткий ответ: компилятор определяет тип по начальному значению переменной и по return функции. Там, где читать нечего, тип пишут сами.
Частая ошибка
Ждать, что тип меняется вместе со значением, как в JavaScript:
let price = 1200;
price = "бесплатно"; // ✗error TS2322: Type 'string' is not assignable to type 'number'.TypeScript вывел тип price один раз — из начального значения 1200, — и дальше этот тип не меняется. Текст для такой цены хранят в отдельной переменной, например let priceLabel = "бесплатно";.
Главное
- Вывод типов: TypeScript сам определяет тип переменной по начальному значению —
let count = 0получаетnumber. - Выведенный тип проверяется так же строго, как аннотация, и после объявления не меняется.
- Тип результата функции выводится из выражения после
return. - У переменной без значения тип
any, поэтому тип такой переменной пишут сами:let total: number;.