Согласно опросу Global Developer Hiring Landscape Survey report 2017, проведенному Stack Overflow, JavaScript является самым востребованным языком программирования среди веб-разработчиков по всему миру. С момента своего создания в 1995 году JavaScript зарекомендовал себя как оптимальный язык работы с интерфейсами для браузеров и веб-страниц. Благодаря богатому набору библиотек он также обеспечил новые возможности для визуализации. Angular[.js], Ember.js и другие подобные фреймворки предоставили JS необходимую гибкость и возможности.
Следует помнить, что JavaScript разрабатывался как клиентский язык для масс, поэтому его функциональность не такая разнообразная, как у других языков. В нем не хватает множества важных функций, необходимых для адекватного написания и поддержки массивных приложений. Чтобы справиться с этой проблемой, веб-разработчики создавали такие инструменты, как eslint для сканирования кода.
Статистика GitHub за последние три года также показала убедительный рост числа проектов, в которых используется статическая типизация JavaScript. Даже в других языках разработчики предпочитают использовать статическую типизацию вместо динамической.
История JavaScript
Mosaic от NCSA был первым общепризнанным веб-браузером еще в 1993 году. А в 1994 Netscape представила свой популярный запатентованный браузер, получивший название Netscape Navigator, который считался единственным надежным вариантом в 90-х годах. Netscape наняла Брендана Эйха в 1995 году, и в том же году им был основан JavaScript. По словам Эйха:
«Мы стремились предоставить «язык-клей» для веб-дизайнеров и программистов на неполный рабочий день, которые строят веб-контент из таких компонентов, как изображения, плагины и мини-приложения на Java. Мы рассматривали Java как «компонентный язык», используемый более дорогостоящими программистами, где «программисты-склейщики» - разработчики веб-страниц - собирали бы компоненты и автоматизировали их с помощью JS».
Допустим. Мы находимся в сложном положении, когда большинство продвинутых языков переходят к функциональному программированию, к строгой и статической типизации.
JavaScript динамически типизированный язык и позволяет объявлять функции, объекты и переменные без объявления типа. Хотя эта возможность и упрощает использование языка, это не всегда удобно. Чтобы помочь справиться с такими проблемами типизации языков программирования, и появлялись TypeScript и Flow.
Цель статьи – выделить плюсы и минусы статической типизации в контексте разработки на Javascript. В дополнение к этому мы рассмотрим TypeScript и Flow, а также сравним их, чтобы в конце этой статьи вы могли бы решить: стоит ли переносить свои проекты на строгую типизацию вместо того, чтобы полагаться на «ванильный JavaScript».
Зачем это нужно
Вспомните Coffeescript, который был чрезвычайно популярен. Но, хотя я очень уважаю его изобретателя, факт заключается в том, что у этого языка были некоторые серьезные проблемы (почитайте соответствующую ветку переписки на ycombinator). Затем появился ES6.
Из-за необходимости поддерживать старые браузеры и для интерактивного выхода функционала ES6 у нас стали появляться транспайлеры, такие как Babel. Coffeescript имеет много общего с ним и тоже является транспайлером.
Инструментов CoffeeScript и Babel было недостаточно, что подтолкнуло сообщество в строну TypeScript и Flow. Взгляните на тренды (за Flow не ручаюсь, думаю, что возникла контекстуальная ошибка, он должен быть в несколько раз меньше).
TypeScript – это язык программирования с открытым исходным кодом, разработанный Microsoft, является суперсетом JS. По другую сторону – Flow, который разработан Facebook.
На практике Flow сравнительно проще, чем TypeScript, и его можно постепенно включить в файл проекта, настроить проверку типа в нем, просто добавив // @flow в начале файла. Все расширения основываются на комментариях.
Flow vs Typescript - сходства и отличия
Конечно, и TypeScript, и Flow полезны. Мы, в свою очередь, развернем сравнение с точки зрения разработчика.
TypeScript
TypeScript, как видно по названию, умеет проверять типизацию. Он принимает на вход (.ts) и генерирует (.js) на выходе. Существует флаг компилятора nolmplicitAny, который, если включен, потребует от вас указать типы и возвращаемые значения для всех используемых аргументов и функций.
Активация noImplicitAny может иметь серьезные последствия для вашей работы, особенно при работе с малоизвестными сторонними модулями. Помимо того, я обратил внимание, что при использовании noImplicitAny я стал писать часть кода специально, чтобы сделать довольным компилятор TypeScript.
Доступно множество описаний интерфейсов для библиотек JS. Если говорить о чем-то популярном, то проблем у вас не будет. Однако, нет уверенности, что разработчик, который написал файл .d.ts, сделал это аккуратно. Плюс ко всему, вам потребуется предоставить определение типов, если вы хотите внедрить стороннюю библиотеку для вашей кодировки. Готовьтесь заплатить за строгую типизацию своим временем.
В дополнение ко встроенной демонстрации ошибок до компиляции, при использовании TypeScript с IDE на подобии WebStorm перед вами откроется перекрестная навигация и более точное автозаполнение.
Flow
В отличие от TypeScript, Flow лишь сканирует ваши .js-файлы для обнаружения возможных ошибок. Другими словами, он действует как умный линтер.
Если пользуетесь Flow, то обратите внимание на пакет для Atom Nuclide.
Все же, кто на вершине?
Независимо от того, кто является вашим фаворитом: TypeScript или Flow, проверка типов – это будущее JS. Примечательным различием между Flow и TypeScript является то, насколько плавно они могут быть интегрированы в текущие проекты. В то время как TypeScript значительно сложнее, Flow относительно легко внедряем, предупреждая по ходу базовой интеграции, что проверяет меньше вашего кода, как и ожидается. Если вы пишете на Angular, то выбор у вас небольшой.
В дополнение ко всему, есть множество других аспектов, о которых стоит задуматься. В сочетании со статической типизацией, TypeScript также нацелен на предоставление гибкого набора инструментов, языковой поддержки рефакторинга и автокомплита.
Преимущества использования статической типизации
Обнаружение ошибок на лету
С помощью тестирования типов легко проверить работоспособность кода еще до его выполнения.
Следующие операции действительны в JavaScript, но вы получите бонус в typescript, например:
static.ts hosted with ❤ by GitHub
Более точная передача смысла функции
Типы действуют как активная, живая документация для автора и его тим-мейтов. Благодаря статической типизации вам легче понять цель функции, тип данных, которые он принимает в качестве входных, или что ожидать взамен.
Если вы считаете, что включение комментариев может сделать то же самое, вы не ошибаетесь. Но поскольку комментарии являются довольно подробными, они нарушают общую структуру кода, уменьшают полезную плотность. Комментарии - это следствие того, что вы не справились с передачей смысла кода в синтаксисе его языка (интересная книга на эту тему: Чистый код Роберта Мартина).
Упрощение отладки ошибок
Нам лучше проверить, что s – строка, а y – регулярное выражение. Без статических типов вам понадобится дополнительный код. А без него нас могут ждать сюрпризы во время выполнения.
Различие между данными и поведением
Поскольку статические типы четко различают данные и поведение, это позволяет разработчикам более уверенно прогнозировать свои ожидания и более точно объяснять цель. Это не только смягчит давление и двусмысленность, но также добавит ясности и прозрачности во время кодинга.
pressure.ts hosted with ❤ by GitHub
Сокращение вероятности возникновения ошибок во время выполнения
Ошибки типа во время выполнения становятся катастрофическими, на чем и живут такие сервисы как Sentry.
Например, приведенный ниже код будет работать в JavaScript, но будет отмечать ошибку компиляции: строка не существует.
helloworld.js hosted with ❤ by GitHub
Инструмент доменного моделирования (если использовать IDE)
Одна из лучших особенностей статических типов. Если вы работали в Visual Studio на языке подобном C#, вы поймете, о чем я. Это реально уменьшает административную сложность. Пример (у вас реально получится работать с субдоменами):
App.subapp.somefunction
Недостатки использования статических типов
Проверка статического типа не лишена недостатков. Мы пройдемся по некоторым недостаткам, которые заслуживают внимания, прежде чем вы сделаете выбор в пользу статической типизации для своих проектов.
Одна из проблем – дополнительная стоимость обучения инженеров и затраты на сопровождение типизированного кода.
Одна из причин, по которой JavaScript настолько популярен среди веб-разработчиков, заключается в его простоте и в том, что им не нужно добираться до полной системы типов перед началом работы. Это особенно важно для начинающих программистов. Включение типов в процесс скорее запутает их и сделает процесс обучения более сложным, чем ожидалось.
С использованием TypeScript или Flow общий размер кода увеличится на 30% как минимум. Плотность кода снижается. Это как Ruby или Java :)
Использование статических типов в JavaScript — Да или Нет?
Выбор сводится к личным предпочтениям и типу проекта, над которым вы работаете. В заключение вы можете выбрать проверку статического типа, если:
- Достаточно большой и комплексный проект
Если ваша команда работает над проектом с большой базой кода, TypeScript поможет обойти множество ошибок. А лучше, чтобы эта база кода сейчас была маленькой или вообще равнялась нулю, тогда вы сможете сократить затраты на интеграцию.
- Над задачей работает большая команда
Чем больше людей, тем сложнее контролировать, что они пишут. Вам легче переложить часть боли машине.
- Рефакторинг программы в перспективе
Используйте TypeScript, если вы считаете, что в будущем потребуется большой рефакторинг. Не взваливайте на себя ненужное бремя, если имеете дело с краткосрочным заданием.
- Ваша команда знакома со статически типизированным языком
Строго типизированные языки, такие как TypeScript, – это прекрасный выбор, если вы или ваши товарищи по команде уже знакомы с типизированными языками, такими как Java или
C# обучением. Так как TypeScript был разработан тем же разработчиком, который изобрел C#, оба эти языка имеют похожие элементы.
- Вы ищите замену babel
TS+ES6 возможно перевести на ES5 с помощью TS-транспайлера. Вы сможете отказаться от babel.
- Библиотека/фреймворк предлагает TypeScript
Для тех, кто использует Angular 2+ или любой другой фреймворк, предлагающий TypeScript, следует попробовать статическую типизацию.
В заключение
Как только вы полноценно перейдете к статической типизации, то вряд ли вернетесь назад. Однако все это зависит от требований и объема проекта, над которым ведется работа. Не стесняйтесь поделиться своими мыслями, оставляйте комментарии. Мы будем рады услышать ваше мнение :).
Олександр Книга, Software Engineer в Weblab Technology
Дмитрий Дмитриенко, Brand Specialist в Weblab Technology
Шармин Хаят, Data Specialist в Weblab Technology