TypeScript никогда не был проще благодаря плагину TypeScript для Babel (@babel/preset-typescript), официальному годовому сотрудничеству между командами TypeScript и Babel. Откройте для себя четыре причины, по которым TypeScript и Babel - идеальная пара, и следуйте пошаговым инструкциям по обновлению вашего проекта с помощью TypeScript за 10 минут.

Хм? Какие? Почему?

Сначала я не понимал необходимости этого нового пресета.

Разве Babel и TypeScript не две совершенно разные вещи? Как Babel может справиться с проверкой типов TypeScript? TypeScript уже может выводить данные в ES5 так же, как Babel, так в чем же смысл? Разве объединение Babel и TypeScript не усложняет ситуацию?

После нескольких часов исследований я пришел к выводу:
TypeScript и Babel - прекрасный союз.

Позволь мне показать тебе.

1) Вы уже используете Babel (или должны).

Вы принадлежите к одной из этих трех категорий:

  1. Вы уже используете Babel. Если не напрямую, то ваша конфигурация Webpack подает *.js файла в Babel (это относится к большинству шаблонов, включая create-response-app).
  2. Вы используете Typescript без Babel. Подумайте о добавлении Babel в свой арсенал, он предоставляет множество уникальных функций. Читать дальше.
  3. Вы не пользуетесь Babel? Пора вскочить на борт.

Пишите современный JavaScript, ничего не ломая.

Ваш код JavaScript должен работать в старом браузере? Нет проблем, Babel конвертирует код и все исправляет. Не беспокоясь использовать новейшие и лучшие функции.

Компилятор TypeScript имеет аналогичную функцию, которую можно включить, задав для target значение типа "ES5" или "ES6". Но конфигурация Babel улучшает это с помощью babel-preset-env. Вместо того, чтобы блокировать определенный набор функций JavaScript (ES5, ES6 и т. Д.), Вы перечисляете среды, которые вам необходимо поддерживать:

"targets": {
    "browsers": ["last 2 versions", "safari >= 7"],
    "node": "6.10"
}

Babel использует compat-table, чтобы проверить, какие функции JavaScript нужно преобразовать и полифилить для этих конкретных целевых сред.

Интересный метод, используемый create-react-app: компилируйте с последними браузерами во время разработки (для скорости) и компилируйте с большим количеством браузеров в производстве (для совместимости). Отлично.

Babel супер настраиваемый.

Хотите JSX? Поток? Машинопись? Просто установите плагин, и Babel справится с этим. Существует огромный выбор официальных плагинов, в основном охватывающих будущий синтаксис JavaScript. И есть множество сторонних плагинов: улучшить импорт lodash, улучшить console.log или strip console.log. Узнайте больше в списке awesome-babel.

Но будь осторожен. Если плагин существенно изменяет синтаксис, то TypeScript может быть не в состоянии его проанализировать. Например, в долгожданном предложении по необязательной цепочке есть плагин Babel:

Но, к сожалению, TypeScript не может понять этот обновленный синтаксис.

Не волнуйтесь, есть альтернатива ...

Вавилонские макросы

Вы знаете Кент Си Доддс? Он создал новый плагин для Babel: babel-plugin-macros.

Вместо того, чтобы добавлять плагины в конфигурационный файл Babel, вы устанавливаете макрос как зависимость и импортируете его в свой код. Макрос запускается, когда Babel компилируется, и изменяет код, как ему нравится.

Вот пример. Используем idx.macro, чтобы почесать наш зуд, пока не придет дополнительное предложение по цепочке.

import idx from 'idx.macro';
const friends = idx(
  props,
  _ => _.user.friends[0].friends
);

Компилируется в:

const friends =
  props.user == null ? props.user :
  props.user.friends == null ? props.user.friends :
  props.user.friends[0] == null ? props.user.friends[0] :
  props.user.friends[0].friends

Макросы довольно новые, но быстро набирают обороты. Тем более что посадка в create-react-app v2.0. CSS в JS охватывает: styled-jsx, styled-components и Emotion. Переносятся плагины Webpack: raw-loader, url-loader и Size-loader. И многие другие, перечисленные на awesome-babel-macros.

Самое приятное: в отличие от плагинов Babel, все макросы Babel совместимы с TypeScript. Они также могут помочь уменьшить зависимости во время выполнения, избежать вычислений на стороне клиента и выявить ошибки на более раннем этапе во время сборки. Прочтите этот пост для более подробной информации.

2) Управлять ОДНИМ компилятором проще.

TypeScript требует наличия собственного компилятора - именно он обеспечивает потрясающие возможности проверки типов.

В пасмурные дни (до 7 Бабеля).

Объединить два отдельных компилятора (TypeScript и Babel) - нелегкая задача. Поток компиляции становится: TS > TS Compiler > JS > Babel > JS (again).

Webpack часто используется для решения этой проблемы. Настройте конфигурацию Webpack, чтобы передать *.ts в TypeScript, а затем передать результат в Babel. Но какой загрузчик TypeScript вы используете? Два популярных варианта - это ts-loader и awesome-typescript-loader. README.md для awesome-typescript-loader упоминает, что он может быть медленнее для некоторых рабочих нагрузок, и рекомендует ts-loader с HappyPack или thread-loader. README.md для ts-loader рекомендует комбинировать с fork-ts-checker-webpack-plugin, HappyPack, thread-loader и / или cache-loader.

Эх. Нет. Это то место, где большинство людей оказывается ошеломленным и помещают TypeScript в «слишком сложную» корзину. Я их не виню.

Яркие солнечные дни (с Babel 7).

Разве не было бы неплохо иметь один компилятор JavaScript? Есть ли в вашем коде функции ES2015, JSX, TypeScript или что-то необычное - компилятор знает, что делать.

Я только что описал Вавилон. Дерзкий.

Позволяя Babel действовать как единый компилятор, отпадает необходимость управлять, настраивать или объединять два компилятора с помощью какого-то замысловатого волшебства Webpack.

Это также упрощает всю экосистему JavaScript. Вместо линтеров, средств выполнения тестов, систем сборки и шаблонов, поддерживающих разные компиляторы, им просто нужно поддерживать Babel. Затем вы настраиваете Babel для удовлетворения ваших конкретных потребностей. Попрощайтесь с ts-node, ts-jest, ts-karma, create-react-app-typescript и т. Д. И используйте вместо них поддержку Babel. Поддержка Babel везде, посетите страницу Настройка Babel:

3) Компилируется быстрее.

Предупреждение! Возможно, тебе захочется присесть за это время.

Как Babel обрабатывает код TypeScript? Удаляет.

Да, он удаляет весь TypeScript, превращает его в «обычный» JavaScript и продолжает свой веселый путь.

Это звучит нелепо, но у такого подхода есть два сильных преимущества.

Первое преимущество: ️⚡️ МОЛНИЯ БЫСТРО ⚡️.

Большинство разработчиков Typescript испытывают медленное время компиляции в режиме разработки / просмотра. Вы пишете код, сохраняете файл и… затем… вот оно… и… наконец, вы видите внесенные изменения. Упс, допустил опечатку, исправьте, сохраните, и… ну. Он просто достаточно медленный, чтобы раздражать и сбивать вас с толку.

Трудно винить компилятор TypeScript, он много работает. Он сканирует файлы определения типа (*.d.ts), в том числе внутри node_modules, и проверяет, правильно ли используется ваш код. Вот почему многие выделяют проверку типа Typescript в отдельный процесс. Однако комбинация Babel + TypeScript по-прежнему обеспечивает более быструю компиляцию благодаря превосходному кэшированию Babel и однофайловой архитектуре генерации.

Итак, если Бабель убирает код TypeScript, какой смысл писать TypeScript? Это подводит нас ко второму преимуществу ...

4) Оставайтесь в зоне, пока вы кодируете.

Вы вместе взламываете какой-то код, быстро придумываете решение, чтобы увидеть, есть ли у вашей идеи жизнеспособность. Вы сохраняете файл, и TypeScript кричит вам:

"Нет! Я не буду компилировать это! Ваш код разбит на 42 разных файла! »

Да, вы знаете, что он сломан. Вы, наверное, тоже провалили несколько модульных тестов. Но сейчас вы просто экспериментируете. Ужасно постоянно следить за тем, чтобы весь код был безопасным по типу все время.

Это второе преимущество Babel, исключающего код TypeScript во время компиляции. Вы пишете код, сохраняете, и он компилируется (очень быстро) без проверки безопасности типов. Продолжайте экспериментировать со своим решением, пока не будете готовы проверить код на наличие ошибок. Благодаря такому рабочему процессу вы всегда будете в нужной зоне, пока вы пишете код.

Итак, как вы проверяете наличие ошибок типа? Добавьте npm run check-types скрипт, вызывающий компилятор TypeScript. Я настраиваю свою команду npm test, чтобы сначала проверить типы, а затем продолжить выполнение модульных тестов.

Это не идеальный брак.

Согласно анонсу, есть четыре функции TypeScript, которые не компилируются в Babel из-за его однофайловой архитектуры вывода.

Не волнуйся, все не так уж плохо. И TypeScript предупредит об этих проблемах, когда включен флаг isolatedModules.

1) Пространства имен.

Решение: не используйте их! Они устарели. Вместо этого используйте стандартные модули ES6 (import / export). Рекомендуемые правила tslint гарантируют, что пространства имен не используются.

2) Приведение типа с синтаксисом <newtype>x.

Решение: используйте вместо этого x as newtype.

3) Константные перечисления.

Какая жалость. На данный момент нужно прибегать к обычным перечислениям.

4) Устаревший синтаксис импорта / экспорта.

Примеры: import foo = require(...) и export = foo.

За все годы работы с TypeScriptin я ни разу с этим не сталкивался. Кто так кодирует? Прекрати!

Хорошо, я готов попробовать TypeScript с Babel!

Давай сделаем это! Это займет всего около 10 минут.

Я предполагаю, что у вас есть установка Babel 7. Если нет, см. Руководство по миграции Babel.

1) Переименуйте файлы .js в .ts

Предполагая, что ваши файлы находятся в /src:

find src -name "*.js" -exec sh -c 'mv "$0" "${0%.js}.ts"' {} \;

2) Добавьте TypeScript в Babel

Несколько зависимостей:

npm install --save-dev @babel/preset-typescript @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread

В вашем конфигурационном файле Babel (.babelrc или babel.config.js):

{
    "presets": [
        "@babel/typescript"
    ],
    "plugins": [
        "@babel/proposal-class-properties",
        "@babel/proposal-object-rest-spread"
    ]
}

TypeScript имеет несколько дополнительных функций, о которых Babel должен знать (с помощью этих двух плагинов, перечисленных выше).

По умолчанию Babel ищет файлы .js, и, к сожалению, это невозможно настроить в файле конфигурации Babel.

Если вы используете Babel CLI, добавьте --extensions '.ts'

Если вы используете Webpack, добавьте 'ts' в resolve.extensions массив.

3) Добавьте команду check-types

In package.json:

"scripts": {
  "check-types": "tsc"
}

Эта команда просто вызывает компилятор TypeScript (tsc).

Откуда tsc? Нам нужно установить TypeScript:

npm install --save-dev typescript

Для настройки TypeScript (и tsc) нам понадобится файл tsconfig.json в корневом каталоге:

{
  "compilerOptions": {
    // Target latest version of ECMAScript.
    "target": "esnext",
    // Search under node_modules for non-relative imports.
    "moduleResolution": "node",
    // Process & infer types from .js files.
    "allowJs": true,
    // Don't emit; allow Babel to transform files.
    "noEmit": true,
    // Enable strictest settings like strictNullChecks & noImplicitAny.
    "strict": true,
    // Disallow features that require cross-file information for emit.
    "isolatedModules": true,
    // Import non-ES modules as default imports.
    "esModuleInterop": true
  },
  "include": [
    "src"
  ]
}

Готово.

Итак, настройка завершена. Теперь запустите npm run check-types (режим просмотра: npm run check-types -- --watch) и убедитесь, что TypeScript доволен вашим кодом. Скорее всего, вы обнаружите несколько ошибок, о существовании которых не подозревали. Это хорошая вещь! Здесь поможет руководство Переход с Javascript.

Руководство Microsoft TypeScript-Babel-Starter содержит дополнительные инструкции по установке, включая установку Babel с нуля, создание файлов определения типа (d.ts) и использование его с React.

А как насчет линтинга?

Используйте tslint.

Обновление (февраль 2019 г.): используйте ESlint! Команда TypeScript фокусируется на интеграции с ESLint с января. ESLint легко настроить благодаря проекту @ typesript-eslint. Для вдохновения ознакомьтесь с моей мега-конфигурацией ESLint, которая включает TypeScript, Airbnb, Prettier и React.

Вавилон + TypeScript = Красивый брак.

Babel - это единственный компилятор JavaScript, который вам нужен. Его можно настроить для обработки чего угодно.

Нет необходимости сражаться с двумя конкурирующими компиляторами JavaScript. Упростите конфигурацию проекта и воспользуйтесь преимуществами потрясающей интеграции Babel с линтерами, программами запуска тестов, системами сборки и шаблонами.

Комбинация Babel и TypeScript молниеносно скомпилирована и позволяет оставаться в определенной зоне при написании кода и проверять типы только тогда, когда вы готовы.

Прогноз: TypeScript вырастет.

Согласно последнему опросу разработчиков Stack Overflow Developer Survey, наиболее популярным языком является JavaScript, а TypeScript занимает 12-е место. Это по-прежнему большое достижение для TypeScript, превосходящее Ruby, Swift и Go.

Я предсказываю, что TypeScript войдет в десятку лучших к следующему году.

Команда TypeScript упорно трудится, чтобы распространять любовь. Этот пресет Babel создавался в течение года, и их новая цель - улучшить интеграцию с ESLint. Это разумный шаг - используйте функции, сообщество и плагины существующих инструментов. Разработка конкурирующих компиляторов и линтеров - напрасная трата усилий.

Путь к TypeScript проложен путем простой настройки конфигурации наших любимых инструментов. Барьер для входа был разрушен.

С ростом популярности VS Code разработчики уже настроили потрясающую среду TypeScript. Автозаполнение на стероидах вызовет слезы радости.

Теперь он также интегрирован в create-react-app v2.0, что делает TypeScript доступным для 200 тысяч загрузок в месяц.

Если TypeScript вас оттолкнул из-за того, что его сложно настроить, это больше не оправдание. Пришло время попробовать.

За JavaScript невозможно угнаться.

Вы используете каждый шанс, который у вас есть. Прокрутка… чтение… обновление… беглый просмотр. Вы потерялись в 42 вкладках браузера со статьями, руководствами и репозиториями GitHub. Вы добавляете несколько закладок, чтобы расплатиться позже (или никогда).

Это потрясающе. Слишком много нужно знать.

Поэтому я разработал систему, которая легко поддерживает меня в курсе последних событий.