Сравнение JavaScript и TypeScript
Дальше: Типы и типизация · История TypeScript · Первая программа · JavaScript — о разделе
JavaScript (JS) и TypeScript (TS) решают одни и те же задачи на вебе и в Node.js, но по-разному относятся к типам данных. В JS тип привязан к значению в момент работы программы. В TS поверх JS добавляется проверка типов до запуска — компилятор и редактор смотрят на контракты в исходном коде и предупреждают о несовместимости заранее.
Полезно держать под рукой базовые статьи:
- типы в JavaScript — как устроена динамическая модель;
- типизация — общие определения статической и динамической проверки;
- что такое код и как он работает — компиляция, интерпретация, шаг от исходника к выполнению.
Термины по статье
| Термин | Коротко | Где углубиться |
|---|---|---|
| Тип данных | Класс значений (число, строка, объект и т.д.) | Типы данных |
| Динамическая типизация | Тип определяется при присваивании и может меняться у одной переменной | типы в JavaScript |
| Статическая типизация | Тип задаётся в коде и проверяется до запуска | типизация, Типы в TS |
| Runtime (среда выполнения) | Момент, когда программа уже запущена в браузере или Node.js | Архитектура компиляции |
| Надмножество | Весь синтаксис JS входит в TS; к нему добавляются типы | История TypeScript |
| Транспиляция | Перевод .ts в .js без смены уровня абстракции (в отличие от компиляции в машинный код) | Компиляция, FAQ по коду |
tsc | Официальный компилятор TypeScript из пакета typescript | Первая программа |
tsconfig.json | Файл настроек проекта (строгость, целевая версия JS, пути) | Форматы и подключение, справочник §11 |
interface | Описание формы объекта — какие поля есть и какого они типа | Синтаксис, Типы |
| Контракт | Договорённость о том, какие данные функция принимает и возвращает | Функции |
| IDE | Среда разработки (VS Code, Cursor, WebStorm) | TypeScript Server |
.d.ts | Файл только с описанием типов, без исполняемого кода | Форматы §декларации |
@types/... | Пакеты с типами для JS-библиотек из DefinitelyTyped | Экосистема |
Два языка, одна среда выполнения
ECMAScript — стандарт, на котором построен JavaScript. TypeScript расширяет этот синтаксис аннотациями типов, interface, дженериками и другими конструкциями, которые исчезают при сборке.
Исходник .ts / .tsx
│
▼
┌──────────────────┐
│ tsc / esbuild │ ← проверка типов, подсказки IDE
│ / Vite / swc │
└────────┬─────────┘
▼
JavaScript (.js) ──► движок (V8, SpiderMonkey, …)
│
└── в .js остаётся только JS; типы стёрты
Цепочка подробно разобрана в Архитектуре компиляции TypeScript и runtime.
Что важно запомнить
- Браузер и Node.js читают JavaScript. Файл
.tsсам по себе в production не исполняется. - TypeScript создан в Microsoft (2012), сейчас развивается как open source на GitHub.
- Любой корректный JS-файл можно постепенно перевести в TS — языки совместимы по синтаксису выполнения.
- TS снижает число ошибок несовместимости типов в коде. Ошибки сети, логики и неверного JSON с сервера по-прежнему ловят тесты и runtime-валидация.
Контекст появления TS — История TypeScript. Краткий обзор в курсе JS — статья 30.
Сводная таблица
| Критерий | JavaScript | TypeScript |
|---|---|---|
| Типизация | Динамическая — тип у значения в runtime | Статическая — контракты в исходнике |
| Когда видны ошибки типов | Часто при работе программы у пользователя | При наборе кода, в tsc, в CI |
| Запуск | Сразу в браузере, Node.js, Deno | После шага транспиляции или dev-сервера с преобразованием на лету |
| Синтаксис | ECMAScript | ECMAScript плюс типы, interface, generics |
| Подсказки в IDE | Базовые | Rename по проекту, переход к определению, автодополнение по типам — TypeScript Server |
| Порог входа | Низкий — .js и тег <script> | Средний — JS, tsconfig, сборка; старт с Первой программы |
| Крупные проекты | Сложнее удерживать единые контракты | Удобнее для команд и monorepo |
| Рефакторинг | Поиск по тексту | Переименование символа с учётом типов |
| Документация API | JSDoc, комментарии | Типы в коде + JSDoc при необходимости |
| Сторонние библиотеки | npm install и импорт | Часто пакет @types/имя или встроенные .d.ts |
| Строгость | Один режим выполнения | Настраивается флагами strict, noImplicitAny — Рекомендации |
| Переход с JS | — | Постепенно через allowJs, JSDoc, переименование в .ts — Миграция |
Один сценарий на двух языках
Функция считает скидку по полю balance у объекта пользователя. Ошибка в типе или в имени поля в JS может долго оставаться незамеченной. В TS её подсвечивает редактор.
JavaScript
function applyDiscount(user, percent) {
return user.balance * (1 - percent / 100);
}
const client = { name: "Анна", balance: "1000" }; // строка вместо числа
console.log(applyDiscount(client, 10)); // "100090" — конкатенация, не скидка
client.balanc = 500; // опечатка в имени поля
applyDiscount(client, 10); // NaN или снова неверный результат
Разбор:
- У
userиpercentнет объявленного типа — функция примет что угодно. - Строка
"1000"в умножении ведёт себя иначе, чем число1000; с оператором+была бы конкатенация строк. - Поле
balancсоздаётся как новое свойство объекта;balanceне меняется, ошибки компиляции нет.
TypeScript
interface User {
name: string;
balance: number;
}
function applyDiscount(user: User, percent: number): number {
return user.balance * (1 - percent / 100);
}
const client: User = { name: "Анна", balance: 1000 };
console.log(applyDiscount(client, 10)); // 900
// const broken: User = { name: "Анна", balance: "1000" };
// Ошибка: Type 'string' is not assignable to type 'number'
// client.balanc = 500;
// Ошибка: Property 'balanc' does not exist on type 'User'
Разбор:
interface Userфиксирует контракт объекта — список полей и их типы.- Несовместимое значение и опечатка в имени поля видны до запуска — в IDE и при
tsc. - В сгенерированный
.jsпопадает обычный JS без: stringи: number— см. Компиляция.
Дальше по типам — сужение (narrowing), union, unknown для данных с сервера.
Практические отличия
Переименование поля в API
JavaScript
- ручной поиск по проекту;
- надежда на тесты и code review;
- риск пропустить вызов в редкой ветке.
TypeScript
- команда Rename symbol в IDE через tsserver;
- компилятор покажет все места, где тип больше не сходится.
Запрос fetch и разбор JSON
JavaScript
- обращение
data.itemsупадёт в runtime, если сервер вернул другую структуру; - ошибка проявится у пользователя или в логах production.
TypeScript
- тип
ApiResponseописывает ожидаемый JSON; - ответ сначала кладут в
unknown, затем проверяют guard-функцией или библиотекой вроде Zod; - примеры HTTP — curl / fetch, TypeScript и Node.js.
React-компонент
JavaScript
- props легко забыть обновить в дочерних файлах после смены API компонента.
TypeScript
type Props = { … }илиinterface Props— компилятор отметит все несовпадения;- подробнее — TypeScript и React, курс JS — React.
Короткий скрипт на 30 строк
JavaScript
- файл
.js, командаnode script.js— минимум настроек.
TypeScript
- настройка
tsconfigи сборки окупается при росте проекта; - для разовых задач часто остаются на JS.
Monorepo (frontend + backend)
JavaScript
- общие контракты дублируют в комментариях или в отдельном README;
- расхождение клиента и сервера заметят поздно.
TypeScript
- общий пакет с типами DTO в одном репозитории — Экосистема, Node.js.
Плюсы JavaScript
- Быстрый старт — файл
script.js, тег<script>илиnode app.jsбез webpack иtsconfig. - Гибкость — одна переменная может хранить разные виды значений; удобно для прототипов.
- Большая экосистема — npm, миллионы пакетов, учебники и ответы на Stack Overflow.
- Простые HTML-страницы — интерактивность без сборщика; см. веб-разработка.
- Один исполняемый формат — тот же JS в браузере, на сервере и в Electron.
Минусы JavaScript
- Ошибки типов в runtime — опечатка в свойстве (
user.emial), лишний аргумент, забытыйawait— см. асинхронность JS. - Тяжёлый рефакторинг — в большой кодовой базе переименование без типов опирается на поиск по тексту.
- Слабая самодокументация — без JSDoc неясно, что ждёт функция, пока не откроешь тело.
- Рост команды — договорённости "в голове" дороже, чем явные контракты в коде.
Плюсы TypeScript
- Раннее обнаружение ошибок — строка вместо числа, лишний аргумент, несуществующее поле, неполный
switchпо union. - Типы как документация — входы и выходы функций видны при вызове в IDE.
- Сильные инструменты — автодополнение, go to definition, безопасное переименование через TypeScript Server.
- Онбординг — новый разработчик читает
interfaceиtypeбыстрее, чем весь граф вызовов. - Постепенное внедрение —
.jsи.tsв одном репозитории, флагallowJs— Рекомендации.
Минусы TypeScript
- Шаг сборки —
tsc, Vite, CI; dev-серверы часто компилируют на лету, но pipeline усложняется. - Больше текста в исходниках — аннотации, дженерики, utility-типы; часть типов выводится автоматически.
- Две темы сразу — нужен JS и система типов (
strictNullChecks, union, generics). - Типы для библиотек — старый пакет без
.d.tsтребует@types/...или ручной декларации — Подключение. - Границы системы — JSON с HTTP и данные из
localStorageTS сам не проверяет; нужны парсеры (Zod, Valibot) и тесты — Обработка ошибок.
Компилятор анализирует ваш исходный код. Данные из сети, форм и файлов нужно валидировать отдельно — см. рекомендации, обработку ошибок и тестирование.
Когда уместен JavaScript
- вы учитесь программировать — JS нужен как база перед TS, см. курс JavaScript;
- нужен небольшой скрипт, автоматизация, bookmarklet или простой лендинг;
- делаете MVP (минимально жизнеспособный продукт) за короткий срок без настройки toolchain;
- проект небольшой, один автор, срок жизни — недели;
- встраиваете фрагмент логики в CMS или legacy, куда нельзя добавить сборку.
Когда уместен TypeScript
- над кодом работает команда;
- архитектура растёт и часто рефакторится;
- в стеке Angular (TS обязателен), React, Vue, Next.js, NestJS;
- нужны общие типы между клиентом и сервером;
- важны предсказуемый онбординг и ревью по контрактам API.
Типичный путь обучения
Учёба → JavaScript (основы, DOM, async)
↓
Первый проект → шаблон Vite react-ts / vue-ts или чистый JS
↓
Рост кодовой → strict TS, общие типы, CI с tsc --noEmit
базы
Весь репозиторий сразу переводить на TS не обязательно. Рабочий порядок — поэтапная миграция:
- включить
allowJs; - типизировать новые модули;
- постепенно поднимать
strict.
TypeScript в индустрии
Опросы Stack Overflow Developer Survey и State of JS стабильно показывают TypeScript среди самых востребованных языков в веб-разработке. В описаниях вакансий на крупные frontend- и fullstack-позиции связка JavaScript + TypeScript встречается чаще, чем только JS без типов.
| Стек | Как используют TS |
|---|---|
| Angular | язык по умолчанию для всего приложения |
| React / Next.js | шаблоны react-ts, типизация props и hooks — статья 21 |
| Vue 3 | <script setup lang="ts"> |
| Node.js / NestJS | DTO, контроллеры, внедрение зависимостей — статья 22 |
| React Native | типы навигации и API |
Отсутствие TS в резюме не закрывает все двери, но в корпоративном frontend и fullstack он почти всегда в стеке.
Распространённые заблуждения
"TypeScript — совсем другой язык, учить с нуля"
"С TypeScript программа работает быстрее"
- В runtime типов нет; скорость как у скомпилированного JS — Компиляция.
"TypeScript убирает все баги"
- Снижает класс ошибок несовместимости типов внутри кода.
- Логика, сеть и внешние данные требуют тестов и валидации.
"В маленьком проекте TS только мешает"
- Для скрипта на десяток строк часто так.
tsc --initи одинinterfaceуже помогают, если проект начнёт расти.
"Нужно писать тип у каждой переменной"
- Вывод типов снимает большую часть рутины — Переменные.
Если вы знакомы с C# или Java
Статическая проверка в TS напоминает C# и Java, но модель структурная — совместимость по набору полей объекта, а не по имени класса. В Java и C# два класса с одинаковыми полями считаются разными типами, пока явно не объявлено наследование.
Подробнее:
Чеклист понимания
- Объяснить, почему браузер выполняет
.js, а не.ts. - Назвать три ошибки, которые TS показывает до запуска, а чистый JS — нет.
- Назвать два случая, когда разумнее остаться на JavaScript.
- Описать цепочку "исходник → компилятор → runtime" своими словами.
- На примере
balanceпоказать разницу динамической и статической типизации. - Объяснить, зачем пакет
@types/lodashи что хранится в.d.ts.
См. также
| Тема | Статья |
|---|---|
| Теория типов в TS | Типы и типизация |
| Первая сборка | Первая программа |
| Миграция JS → TS | Рекомендации |
| Компиляция и runtime | Архитектура компиляции |
| Синтаксис типов | Синтаксис |
| Дженерики | Дженерики |
| Обзор в курсе JS | TypeScript |
| Динамические типы JS | Типы в JavaScript |
| Справочник-шпаргалка | 301 |
| Итоги раздела | TypeScript — итоги |
| Самопроверка | Чек-лист |