Зачем нужны типы: проблемы динамического JavaScript

Откуда взялся TypeScript и какой класс ошибок он убирает из JavaScript.

TypeScript — это надмножество JavaScript, которое добавляет статическую типизацию: типы проверяются компилятором до запуска программы.

Боль динамической типизации

JavaScript не проверяет типы заранее. Любая переменная может в любой момент стать чем угодно: числом, строкой, объектом, undefined. Это удобно для быстрых скриптов, но в больших проектах превращается в источник тихих багов, которые всплывают только в рантайме — иногда уже у пользователя.

Классический пример: функция ждёт число, а получает строку. JavaScript не возмутится — он молча выполнит что-то неожиданное.

function addTax(price) {
  return price * 1.2;
}

console.log(addTax(100));      // 120 — ок
console.log(addTax("100"));    // строка вместо числа
console.log(addTax(undefined)); // забыли передать аргумент

Вывод:

120
120
NaN

Строка "100" неявно привелась к числу — повезло. А вот undefined * 1.2 дало NaN («не число»), и эта ошибка поедет дальше по коду, ломая расчёты в совсем другом месте. Найти источник такого бага бывает мучительно долго.

Опечатки, которые никто не ловит

Ещё одна частая беда — обращение к несуществующему свойству. JavaScript вернёт undefined вместо того, чтобы сказать «такого поля нет».

const user = { name: "Аня", age: 30 };

console.log(user.nmae); // опечатка в имени свойства
console.log(user.email); // свойства вообще нет

Вывод:

undefined
undefined

Программа не падает — она просто работает неправильно. В большом проекте такие undefined расходятся как круги по воде.

Как помогает TypeScript

TypeScript описывает, какого типа должны быть данные, и проверяет это до запуска. Тот же код с типами компилятор отвергнет с понятной ошибкой:

function addTax(price: number): number {
  return price * 1.2;
}

addTax("100");
// Ошибка: Argument of type 'string' is not assignable to parameter of type 'number'.

const user = { name: "Аня", age: 30 };
console.log(user.nmae);
// Ошибка: Property 'nmae' does not exist on type '{ name: string; age: number; }'.

Эти ошибки видны прямо в редакторе, красным подчёркиванием, ещё во время написания кода. Баг исправляется за секунды, а не ищется часами по логам.

Что важно понять про типы

  • Типы существуют только на этапе разработки. После компиляции они исчезают — в браузер уезжает обычный JavaScript без какой-либо проверки типов в рантайме.
  • TypeScript не замедляет программу. Он не добавляет проверок во время выполнения; вся работа делается компилятором заранее.
  • Это надмножество JS. Любой валидный JavaScript — уже валидный TypeScript. Можно подключать типы постепенно.

Где это реально спасает

Проблема в JSЧто делает TS
Передали строку вместо числаОшибка компиляции до запуска
Опечатка в имени свойстваПодсказка и ошибка в редакторе
Забыли обработать nullЗаставляет проверить значение
Рефакторинг большого проектаПоказывает все места, где сломалось

Итог

  • Динамическая типизация JS откладывает ошибки до рантайма — и они дорого обходятся.
  • TypeScript добавляет статические типы и ловит целый класс багов ещё в редакторе.
  • Типы живут только при разработке и не влияют на скорость готовой программы.
Проверьте себя
1. Когда TypeScript проверяет типы?
AВо время выполнения программы в браузере
BДо запуска, на этапе компиляции
CТолько при деплое на сервер
DНикогда, типы — это просто комментарии
2. Что происходит с типами TypeScript после компиляции в JavaScript?
AОни превращаются в проверки во время выполнения
BОни исчезают — в рантайм уходит обычный JS
CОни сохраняются в отдельном файле и проверяются браузером
DОни замедляют выполнение программы
3. Почему вызов addTax(undefined) в JavaScript опасен?
AПрограмма сразу аварийно завершится
BВернётся NaN, и ошибка тихо распространится дальше по коду
CJavaScript автоматически подставит ноль
DБраузер выведет предупреждение в консоль
Поддержать проект