Хотите заказать веб-сайт? Связаться с нами

Target в TypeScript: под какую версию JS

На прошлом занятии мы разобрались, какие файлы tsc читает и создаёт. Но один и тот же TypeScript-код можно превратить в совершенно разный JavaScript — всё зависит от того, под какую версию языка вы компилируете. Сегодня разберём флаг --target, а заодно познакомимся с флагом --removeComments.

Target в TypeScript: под какую версию JS

Подготовка

Создайте файл modern.ts со следующим содержимым:

// Возвращает никнейм пользователя, либо значение по умолчанию
type User = {
  profile?: {
    nickname?: string;
  };
};
 
function getNickname(user: User): string {
  return user.profile?.nickname ?? "Guest";
}
 
const greet = (name: string) => `Hello, ${name}!`;
 
console.log(greet(getNickname({})));

Здесь используется сразу несколько современных возможностей JavaScript: опциональная цепочка ?., нулевое слияние ??, стрелочная функция и шаблонная строка. Посмотрим, что с ними произойдёт при компиляции под разные версии языка.

Один код — разный JavaScript на выходе

Шаг 1: Компилируем под ES5

Запустите:

npx tsc modern.ts --target es5

Получившийся modern.js выглядит совсем не так, как исходник:

// Возвращает никнейм пользователя, либо значение по умолчанию
function getNickname(user) {
    var _a, _b;
    return (_b = (_a = user.profile) === null || _a === void 0 ? void 0 : _a.nickname) !== null && _b !== void 0 ? _b : "Guest";
}
var greet = function (name) { return "Hello, " + name + "!"; };
console.log(greet(getNickname({})));

Компилятору пришлось эмулировать опциональную цепочку и нулевое слияние через временные переменные и проверки на null/undefined, стрелочную функцию превратить в обычную, а шаблонную строку — в конкатенацию.

Шаг 2: Компилируем под ES2020

Теперь укажите более современную цель:

npx tsc modern.ts --target es2020

Результат почти не отличается от исходного кода:

// Возвращает никнейм пользователя, либо значение по умолчанию
function getNickname(user) {
    return user.profile?.nickname ?? "Guest";
}
const greet = (name) => `Hello, ${name}!`;
console.log(greet(getNickname({})));

ES2020 нативно поддерживает и опциональную цепочку, и нулевое слияние, и стрелочные функции — компилятору осталось только убрать типы.

Вот несколько распространённых значений target и когда их обычно выбирают:

Target Когда использовать
es5 Нужна поддержка старых браузеров, включая Internet Explorer 11
es2015 Классы, let/const, стрелочные функции нативно, без полифиллов
es2017 Добавляется нативная поддержка async/await
es2020 Опциональная цепочка, нулевое слияние, BigInt
esnext Самые свежие возможности — для окружений с бандлером, который доработает остальное

Не выбирайте target наугад — посмотрите, какие браузеры или версии Node.js реально нужно поддерживать. Для бэкенда на актуальном Node.js обычно спокойно подойдёт es2020 или выше, а вот фронтенд стоит сверять со своим списком поддерживаемых браузеров (browserslist), если он есть в проекте.

Ещё один полезный флаг: --removeComments

Шаг 3: Комментарий по умолчанию остаётся

Обратите внимание — в обоих файлах из шагов 1 и 2 комментарий из исходника сохранился без изменений. По умолчанию tsc ничего не делает с комментариями, просто переносит их в результат как есть.

Шаг 4: Убираем комментарии флагом —removeComments

Если комментарии не нужны в финальной сборке, добавьте флаг:

npx tsc modern.ts --target es2020 --removeComments

Теперь modern.js становится чище:

function getNickname(user) {
    return user.profile?.nickname ?? "Guest";
}
const greet = (name) => `Hello, ${name}!`;
console.log(greet(getNickname({})));

Комментарий исчез, а логика кода осталась прежней.

Запуск и проверка

Сравните все варианты ещё раз, чтобы увидеть разницу своими глазами:

npx tsc modern.ts --target es5
npx tsc modern.ts --target es2020
npx tsc modern.ts --target es2020 --removeComments

Первая команда даст громоздкий ES5-код с полифиллами, вторая — почти нетронутый ES2020, третья — тот же ES2020, но уже без комментария.

Бонус: как выбрать target на практике

  1. Проверьте версию Node.js в проекте командой node -v — современные LTS-версии спокойно понимают es2020 и выше.
  2. Если в проекте уже настроен browserslist, ориентируйтесь на него, а не выбирайте target вручную «на глаз».
  3. В проектах с бандлером (Vite, esbuild, webpack) часто выгоднее оставить esnext в tsconfig.json и доверить понижение синтаксиса самому бандлеру.

Если сомневаетесь, какой target выбрать, начните с esnext и понижайте только тогда, когда столкнётесь с реальной проблемой совместимости. Слишком ранний ES5 может незаметно раздувать размер бандла полифиллами, которые никому не нужны.

Итог

Сегодня мы увидели, как один и тот же TypeScript-код превращается в разный JavaScript в зависимости от настроек:

  1. Флаг --target определяет версию JavaScript на выходе — от старого es5 до самого свежего esnext.
  2. Чем ниже target, тем больше современного синтаксиса компилятору приходится эмулировать вручную.
  3. Флаг --removeComments убирает комментарии из скомпилированного файла.
  4. Target стоит выбирать исходя из реальной среды выполнения, а не наугад.

В следующем уроке перейдём от отдельных флагов к полноценной настройке проекта — создадим tsconfig.json и разберёмся, как хранить все эти параметры в одном месте.

Теги: