Один из первых интерфейсных проектов, которые я написал, был на платформе GWT (Google Web Toolkit). GWT - это среда на основе Java, которая переносит код на JavaScript. Мне он нравился, потому что он давал мне надежную типизацию, тогда как JavaScript - нет. Через некоторое время мне нужно было раздвинуть границы того, что определено во фреймворке, поскольку я хотел использовать новые функции языка JavaScript. JavaScript быстро менялся, и с каждым новым выпуском Chrome открывались новые возможности для исследования. Таким образом, я закончил тем, что написал привязки веб-платформы для GWT вместо того, чтобы сосредоточиться на приложении, которое у меня было в руках. Через некоторое время я решил все переделать с помощью чистого JavaScript вместо Java. После этого я понял, как сильно мне не хватает типов в JavaScript. Но, учитывая мой опыт работы с GWT (хотя и очень положительный, мне все же пришлось написать много кода, относящегося к GWT, а не к моему приложению), я не хотел возвращаться к строго типизированным языкам. Очень гибкая веб-платформа предлагала гораздо больше. А потом на горизонте появился TypeScript. Мои коллеги пытались убедить меня использовать его. Я попробовал. В результате я делал почти то же самое, что и с GWT. Мне нужно было позаботиться о своей среде разработки, а иногда и о привязках к веб-платформе. Не говоря уже о постоянном ожидании компиляции кода. В конце концов, я не вижу большой разницы между GWT и TypeScript. И я сравниваю эти два, поскольку оба являются интерфейсными фреймворками со сложными типами.

Я поддержал свое решение писать код на чистом JavaScript, поскольку это дает мне максимальную гибкость. Затем я написал три экосистемы веб-компонентов (я сейчас пишу) и понял, что использование типов неизбежно в большем масштабе. Но как это сделать, не переписывая все снова и снова? Я написал сотни компонентов, и о их переносе на новый фреймворк не могло быть и речи. Затем я начал изучать инструменты, доступные для проектов на чистом JavaScript. Видимо, вся экосистема двинулась вперед. Ответ на мою проблему был прямо передо мной. Вы можете использовать TypeScript вместе с чистым JavaScript, практически не меняя код. Как это возможно?

Как всегда, ответ - в правильных инструментах. Сначала я переключаюсь с Atom на VS Code. Атом великолепен. У него лучшая эргономика и лучший опыт разработчиков. VS Code намного уступает Atom. Однако VS Code имеет более обширную экосистему плагинов и лучшую поддержку. Во-вторых, я начал использовать TypeScript в своих проектах. Видите ли, у TypeScript есть два варианта компиляции: allowJs и checkJs. Они инструктируют компилятор TypeScript включать файлы JavaScript в свою обработку, а затем проверять наличие ошибок компиляции. Почему VS Code важен? В его ядро ​​встроена поддержка TypeScript. Таким образом, с правильными плагинами и конфигурацией вы получаете поддержку TypeScript в обычных файлах JavaScript. Но где же типы? Ну, в тоннах библиотек, которые вы устанавливаете из npm, уже есть типы. Когда вы импортируете модуль в свой код (я предполагаю, что вы уже перешли на модули ES), типы уже загружены для вас. Поэтому, когда вы начинаете использовать импортированную библиотеку, вы получаете автозаполнение и проверку типов бесплатно. Если библиотека не предлагает свои собственные типы, вы, вероятно, можете установить типы из пакета @types/library-name, который автоматически загружает типы библиотеки.

Итак, давайте посмотрим, как может выглядеть такая конфигурация. Чаще всего я использую следующий (файл tsconfig.json):

{
 “compilerOptions”: {
   “target”: “esnext”,
   “module”: “esnext”,
   “moduleResolution”: “node”,
   “lib”: [“es2017”, “dom”],
   “allowJs”: true,
   “checkJs”: true,
   “noEmit”: true,
   “strict”: false,
   “noImplicitThis”: true,
   “alwaysStrict”: true,
   “esModuleInterop”: true
 },
 “include”: [ “**/*.js”,]
}

Затем я устанавливаю библиотеку typescript в качестве зависимости разработчика от моего проекта.

...
"devDependencies": {
  "typescript": "^4.0.0"
  ...
}

И вуаля. В тот момент, когда вы импортируете любую библиотеку, и в этой библиотеке есть определенные типы, вы автоматически получаете поддержку TypeScript.

И это обычный файл JavaScript! В этом конкретном примере я установил the@types/node typings.

Теперь TypeScript предлагает нечто, называемое файлами объявлений TypeScript. Вот что такое @types/node. Это не версия NodeJs на TypeScript, а скорее объявление библиотеки JavaScript. Файл объявления не содержит никакой логики, а скорее сообщает компилятору TypeScript, чего ожидать от библиотеки. Ниже приводится пример такого объявления для приложения ленты новостей:

Интерфейс в TypeScript сообщает компилятору, какова структура данных типа, который вы обрабатываете в приложении. Чтобы использовать свой собственный тип в файле JavaScript, вы используете нотацию JSDoc для импорта определения:

/** @typedef {import('./types').NewsItem} NewsItem */

typedef сообщает компилятору, что в этом месте определяется тип. Его можно определить встроенным, но наличие всех типов в одном файле для вашего проекта упрощает задачу. Тогда инструкция import аналогична импорту обычного модуля ES. После импорта вы сообщаете компилятору, какой тип вы хотите импортировать. В данном случае он NewsItem определен в файле types.d.ts. Последняя часть сообщает компилятору, как вы хотите, чтобы этот тип вызывался локально в вашем файле. Вы, вероятно, будете использовать то же имя, хотя у меня было несколько случаев, когда мне нужно было переименовать тип из-за конфликта имен. Наконец, вы используете комментарии JSDoc, чтобы использовать импортированные таким образом типы в вашем коде.

Последнее распространенное использование типов - это приведение типов. Довольно часто вам нужно преобразовать тип unknown или any к другому, который вы хотите использовать. Например, если функция getFeed() не была должным образом аннотирована типом, вы можете преобразовать этот тип в строку, чтобы получить ту же поддержку. Смотрите разницу на следующем снимке экрана.

Вы приводите тип, добавляя аннотацию @type и заключая выражение, которое вы хотите преобразовать, в квадратные скобки.

const typedValue = /** @type TypeName */ (variableOrExpression);

Вывод

Как оказалось, вам не нужно выбирать между TypeScript и JavaScript. Вы можете использовать и то, и другое, пока ваш базовый код написан на JavaScript. Вы не можете использовать исходные файлы TypeScript таким образом, они всегда должны быть скомпилированы, но, по крайней мере, вы получаете единственное преимущество использования системы TypeScript: types. Вы должны попробовать это сегодня в своем проекте, и я могу гарантировать вам, что вы никогда больше не вернетесь к написанию файлов на чистом JavaScript без добавления поддержки TS. Это сэкономит вам много времени, потому что не позволит вам совершать ошибки, которые в противном случае было бы так сложно найти. Если у вас есть другой опыт, поделитесь с нами. Следите за новостями, чтобы увидеть больше подобных статей от меня.