История о том, как мы перевели проект в почти четверть миллиона строк на TypeScript и остались в живых

https://hashnode.com/post/how-we-migrated-a-200k-loc-project-to-typescript-and-survived-to-tell-the-story-ciyzhikcc0001y253w00n11yb
  • Перевод
В 2016-м статически типизированный JavaScript оказался крайне востребованным. Теми или иными средствами, позволявшими устранить недостатки динамической природы JS, воспользовались многие компании. Нас тоже привлекла перспектива задействовать огромный потенциал статической типизации в своих разработках.


Выбирая инструменты, мы предварительно остановились на TypeScript и Flow. Хотя проекты эти и различаются, направлены они на решение одной и той же задачи. А именно, позволяя контролировать типы данных, они обеспечивают более совершенную, в сравнении с чистым JS, организацию кода, улучшают возможности рефакторинга, позволяют программистам работать быстрее и увереннее.

Coherent Labs и TypeScript


Мы начали присматриваться к типизированному JS в прошлом году, когда проект, над которым я сейчас работаю, визуальный редактор пользовательских интерфейсов для HTML-игр, написанный преимущественно на JavaScript, дорос до более чем 100 тысяч строк кода. Редактор оснащён массой возможностей, как результат, его кодовую базу стало сложнее поддерживать и подвергать рефакторингу. Именно поэтому мы решили провести некоторые исследования и найти решение для встающей перед нами проблемы.

Через некоторое время мы пришли к двум вариантам — TypeScript и Flow. Оба обещали дать нам статические типы для улучшения контроля над кодом, но одного этого было недостаточно. Мы хотели использовать всю мощь ES6 и будущих версий языка. Flow, по сути, это статический анализатор кода, что означает, что нам пришлось бы использовать транспилятор для всего нашего ES6-кода, но применяя TypeScript, который является надстройкой над JavaScript, мы получили бы и статические типы, и поддержку большинства последних возможностей ECMAScript.

Учитывая вышесказанное, было несложно принять окончательное решение. Мы остановились на TypeScript.

О популярности статически типизированного JavaScript


Давайте немного отвлечёмся и поговорим о том, что такое статическая типизация, и как она нашла своё место в динамическом мире JavaScript.

Основная разница между статически типизированными и динамически типизированными языками заключается в том, как они производят проверку типов данных. Первые делают это во время компиляции, а вторые — во время исполнения программы. Другими словами, статически типизированные языки требуют от программиста объявлять типы данных перед их использованием, в то время как в динамически типизированных языках это не нужно.

JavaScript, являясь динамически типизированным языком, позволяет использовать различные типы данных в разнообразных операциях. Для разработчиков, которые пришли в JS со статически типизированных языков, вроде Java или C++, это, в большинстве случаев, выглядит совершенно нелогично и даже странно. Подобное приводит к серьёзным неприятностям в проектах большого масштаба. Например, программисту может понадобиться потратить многие часы только на то, чтобы выяснить, отчего вдруг некая переменная оказалась NaN.

TypeScript и Flow были созданы для решения подобных проблем. Поддержкой Flow, который приобрёл популярность в последние два года и ориентирован лишь на проверку типов, занимается Facebook. TypeScript же, к которому приложила руку Microsoft, с другой стороны, является надстройкой над JavaScript. Это означает, что он не только поддерживает проверку типов, но и позволит работать с будущими возможностями ES6 и ES7. И у того, и у другого, имеются компиляторы, преобразующие код в чистый JavaScript, который можно запустить в любом браузере.

Вот некоторые преимущества использования типизированного JavaScript:

  • Он позволяет улучшить читаемость кода.
  • Он способствует раннему выявлению ошибок.
  • Он даёт возможности для более надёжного рефакторинга.
  • Он улучшает поддержку языка на уровне IDE.

Принимая решение о возможной разработке проектов с использованием типизированного JavaScript, задайте себе следующие вопросы:

  • Значителен ли проект для вашего бизнеса?
  • Состоит ли проект из множества сложных частей?
  • Есть ли вероятность того, что вы соберётесь подвергнуть проект рефакторингу для того, чтобы он лучше соответствовал вашим потребностям?
  • Есть ли у вас большая команда, в которой разработчикам необходимо до минимума сократить время на изучение кодовой базы и поддержку собственных знаний о ней в актуальном состоянии?

Если большинство ответов на эти вопросы положительны, значит вам стоит рассмотреть возможность переноса проекта на TypeScript или Flow.

Вечная битва титанов: TypeScript и Flow


Как уже было сказано, и Flow, и TypeScript дают JS-разработчику очень важную, и, по моему мнению, весьма необходимую возможность — систему типов.

TypeScript появился в 2012-м, при содействии Microsoft, когда Андерс Хейлсберг выпустил его первый релиз. Кроме прочего, он поддерживает необязательные аннотации типов и возможности ES6 и ES7. У него имеется компилятор, который обрабатывает аннотации и генерирует код на обычном JavaScript.

Flow — это статический анализатор кода, которым занимается Facebook. Он спроектирован так, чтобы быстро находить ошибки в JavaScript-приложениях. Это — не компилятор, а анализатор. Он может работать вообще без каких-либо аннотаций типов, отлично показывая себя в задаче вывода типов переменных.

Взглянем на простой пример. Имеется следующая функция, которая, принимая имя, возвращает приветствие:

function greet = function(name) {
   return `Hello, ${name}!`;
}

И с использованием TypeScript, и с применением Flow, эта функция будет выглядеть примерно так:

function greet(name: string): string {
   return `Hello, ${name}!`;
}

«String» после параметра функции — это способ задания типа в TypeScript и Flow. Типы могут быть как простыми, так и составными. Это означает, что если мы попытаемся использовать аргумент, тип которого отличается от заданного, будет выдано сообщение об ошибке. Рассмотрим пример использования функции.

const message = greet(43);

Функцию мы вызвали, передав ей в качестве аргумента число. При компиляции кода TypeScript выведет сообщение о том, что произошла ошибка:

Argument of type 'number' is not assignable to parameter of type 'string.'

Вылавливание подобных ошибок во время компиляции может весьма положительно сказаться на производительности труда и даже на настроении разработчика. TypeScript, кроме того, поддерживает современные возможности JS, такие, как стрелочные функции, импорт и экспорт, генераторы, механизмы async/await, классы, и так далее. В итоге оказывается, что TypeScript позволяет сформировать отличную экосистему разработки приложений на JavaScript.

Итак, теперь позвольте мне рассказать о том, как мы перевели проект, содержащий более 200 тысяч строк кода, на TypeScript.

Шаг первый — выбор технологии


Наш проект стремительно развивался, со временем объём кодовой базы увеличивался практически экспоненциально. В те времена росла популярность TypeScript и статически типизированного JavaScript. Во всём этом мы увидели возможность, которую нам не следовало упускать. После некоторых изысканий и пары совещаний мы остановились на двух возможных походах:

  • Использовать Flow и Babel для транспиляции ES6.
  • Использовать TypeScript и его компилятор для ES6/ES7 компиляции.

Мы выбрали именно TypeScript по нескольким причинам:

  • В те времена у TypeScript было более обширное сообщество, по нему было больше материалов.
  • Нам не хотелось усложнять процесс сборки приложения, который и так был довольно тяжёлым. Добавление ещё двух шагов при использовании Flow (компиляция Flow и транспиляция Babel) замедлили бы работу ещё сильнее. TypeScript же позволял обойтись одним дополнительным этапом сборки, что показалось нам вполне приемлемым.
  • TypeScript лучше поддерживают интегрированные среды разработки. Вся наша команда пользуется WebStorm, которая обеспечивает отличную поддержку TypeScript.
  • Поддержка ES5. Ядро нашей системы построено на WebKit и JavaScriptCore, с учётом определённых ограничений. Некоторые из стандартных возможностей ES5 не поддерживаются. В результате, возможности TypeScript сыграли ведущую роль при принятии окончательного решения.

После шести месяцев работы, я могу откровенно сказать, что выбор TypeScript был верным решением. Не всё в процессе переноса проекта шло гладко, но ни с чем слишком сложным мы не столкнулись.

Шаг второй — начало


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

Далее была настройка сборочного инструмента (Grunt) с использованием grunt-ts, и, дня через полтора, первый TypeScript модуль был готов. Главной трудностью тогда была работа с глобальными и внешними модулями. TypeScript имеет жёсткие правила, касающиеся типизации. Как результат, компилятор TypeScript не распознаёт вспомогательные библиотеки, вроде jQuery и Kendo UI, и их методы. Это сразу же дало более 200 ошибок компиляции, указывающих на то, что TypeScript не может найти переменную типа «$». Решение было довольно простым — мы воспользовались инструкциями declare:

declare var $;
declare var kendo;
...

Ключевое слово declare используется для создания так называемых окружающих объявлений. Они служат для предоставления TypeScript информации о других библиотеках, о типах данных, источником которых является не TS-файл. В той ситуации это оказалось вполне приемлемым решением.
На данном этапе мы успешно перевели на TypeScript первый модуль и были готовы уйти в работу с головой, переводя весь проект на TypeScript.

Шаг третий — переход


Следующим шагом был перевод всех остальных модулей на TypeScript. Некоторые из них были сильно взаимосвязаны и надо было придумать способ быстро сделать их работоспособными. После некоторых дополнительных исследований и пары часов мозговых штурмов, мы пришли к сравнительно простой стратегии.

Для начала мы переименовали все файлы, дав им расширение .ts, и тут же столкнулись со шквалом ошибок компиляции. Затем добавили необходимые объявления TypeScript и назначили некоторым переменным тип данных Any. Это позволяет записывать в переменную данные различных типов. Таким способом объявляли переменные, которые могут хранить данные разных типов, скажем, строки, числа, логические значения.

После двухдневной борьбы с типами и объявлениями, мы вышли на первую полную компиляцию TypeScript. Однако, работы оставалось ещё очень много. Надо было улучшить проверку типов, добавить соответствующие объявления для внешних библиотек и подвергнуть ES5-код переработке под стандарты ES6.

Файл объявлений описывает устройство библиотеки. Применяя их (ещё их называют файлами .d.ts), можно избежать неправильного использования библиотек и получить удобства вроде автозавершения команд в редакторе кода. При работе с TypeScript 1.8 для того, чтобы добавить новый файл объявлений, нужно установить отдельные npm-пакеты глобально, найти файлы объявлений для конкретной библиотеки и сохранить все файлы описаний библиотек в папке «typings». Честно говоря, решение это было не самое элегантное. В TypeScript 2.0 имеется новый способ управления объявлениями библиотек — использование реестра npm. Делается это всё теперь парой команд. Сначала — установка:

npm install --save @types/jquery

Потом — импорт там, где это нужно:

import * as $ from 'jquery'

В результате — нет больше скучной возни с файлами и папками.
Итак, с внешними библиотеками мы разобрались. Следующим шагом было изменение всех объявлений с типом Any на подходящие типы данных. Эта задача заняла несколько дней. Мы решили не торопиться и поэтапно перерабатывать код. В частности, выполняли рефакторинг под ES6 и изменение типов. После пары недель мы инкрементально перевели на ES6 80% кода, снабдив его осмысленными аннотациями типов. На данном этапе можно было переходить к следующей стадии работы — тестированию.

Тестирование и TypeScript


Наша среда разработки была близка к идеалу и мы были готовы к следующему большому этапу работы над проектом — сквозному (E2E) тестированию. Мы решили использовать средства JavaScript. Наш арсенал — это Mocha, Chai, Selenium и WebDriver Selenium. Мы изолировали код тестирования — фреймворк Selenium, тесты и все зависимости, предоставив им отдельный tsconfig.json.

Присутствие файла tsconfig.json в директории указывает на то, что директория является корнем проекта TypeScript. Этот файл задаёт корневые файлы и параметры компилятора.

Нам пришлось создать один такой файл для самого проекта и подвергнуть рефакторингу задачу Grunt для корректного использования разных конфигурационных файлов. Теперь мы были готовы начать работу с фреймворком Selenium.

Структура фреймворка состоит из семи основных и пяти вспомогательных модулей. Вот основные модули:

  • Обработчик драйвера, который запускает и останавливает Selenium и управляет тайм-аутами.
  • Модуль селектора, содержащий все элементы, которые используются в тестах.
  • Главный файл действий, который ответственен за организацию работы с различными частями приложения и выполнение взаимодействий с ним, вроде щелчков мышью, выделения элементов, ввода данных.
  • Модуль для экспорта и удаления ресурсов.
  • Модуль ведения журналов.
  • Модуль создания копий экрана, который делает скриншот после каждого проваленного теста.
  • Модуль для имитации API бэкенда.

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

Кроме того, мы добавили средство создания отчётов — mochawesome, которое выводило полный отчёт по всем тестам после их завершения.

Благодаря TypeScript в проекте удалось задействовать возможности async/await, в результате, мы пришли к более чистому и лучше организованному коду.

Планы на будущее


На самом деле, то, о чём я рассказал, это только начало. Переход на TypeScript — лишь капля в море. Сделать нам предстоит ещё очень много. Вот некоторые из наших планов:

  • Произвести рефакторинг всей архитектуры проекта.
  • Добавить новые функции, такие, как 3D-выделение и ограничительные рамки, визуальные указатели привязки данных элементов и многое другое.
  • Улучшить общее время исполнения тестов. Сейчас для выполнения 440 тестов требуется порядка 30 минут.

Кроме того, мы экспериментируем с библиотеками, поддерживающими работу с виртуальным DOM, наподобие React и InfernoJS. И та и другая отлично поддерживают TypeScript, проект может значительно выиграть от прироста производительности, который даёт работа с виртуальным DOM.
Мы внимательно следим за развитием TypeScript. Последние релизы представляют новые возможности, вроде отображения типов, операторов spread и rest для работы с объектами, поддержки асинхронных функций при компиляции в ES3 и ES5. В будущих релизах ожидается поддержка генераторов для ES3/ES5, улучшение средств обобщённого программирования, асинхронные итераторы.

Итоги


Решение использовать TypeScript в нашем проекте оказалось правильным, принесло много хорошего. В частности, это — повышение производительности труда, улучшение управляемости кода, поддержка ES6. Изначально я с недоверием относился к TypeScript, но после работы с ним могу сказать, что он — это то, чего мне очень долго не хватало.

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

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

Уважаемые разработчики! А как вы относитесь к средствам статической типизации в JavaScript? Если бы вы решили переработать большой JS-проект, что бы вы выбрали?
Метки:
RUVDS.com 444,92
RUVDS – хостинг VDS/VPS серверов
Поделиться публикацией
Похожие публикации
Комментарии 53
  • +4
    Уважаемые разработчики! А как вы относитесь к средствам статической типизации в JavaScript? Если бы вы решили переработать большой JS-проект, что бы вы выбрали?
    Предлагаю добавить опрос к статье, чтобы вопрос не был риторическим.
    • +3
      Сколько времени у вас длится компиляция с TypeScript в JavaScript, раз уж речь идет о 250,000 строках кода? По личному опыту наблюдений на слабеньких машинках (например, Macbook Pro 13 2012 года) средний эдакий проект размером с 1000-1500 файлов компилируется около 20-30 секунд, а на мощных десктопах (как то Core i7-6700) от 8 до 15 секунд.

      В принципе, эти цифры не такие и страшные, но не ропщут ли ваши разработчики, что раньше ждать ничего было не надо (если писать на ES5, скажем чисто для примера), а теперь на каждое изменение нужно сколько-то еще и ждать?

      Конечно же, TypeScript со своей стороны предлагает пару-тройку вариантов ускорения сборки, но интересно, какие методики вы у себя в проекте используете дабы не ждать подолгу завершения компиляции?
      • +4
        Я верю в С++ и Вы оскорбляете мои чувства!
        • 0

          Схожий проект, файлов под 1000


          Единственное что существенно помогло — компиляция в гранте через модуль concurrent.


          С помощью него комбайним необходимые таски и они компайляться паралельно. В случае с одним таком — единственное что нашли — разбить его на саб-таски и компайлить паралельно.


          В целом на air 15го года в 5 секунд влаживаеться


          Были попытки также паралельно компайлить на сервере с xeon, но подружить с ядрами / потоками как-то не получилось и прирост не был таким большим.


          Если есть какие-то другие идеи / варианты тоже рад был бы услышать.

        • +1

          Для меня в тайпскрипте был бы смысл, если бы благодаря строгой типизации он был быстрее обычного жс. Да и после выхода es6 код стал намного более читаем. Идеальным для жс кажется то, что сейчас имеется в 6м перле — строгой типизации нет, но если добаляешь типы то все работает быстрее.

          • +4
            TypeScript ровно это и делает, типизация опциональна. Но в ней достаточно смысла.
            • +1

              Как Typescript может сделать ваш код быстрее если бы вы писали обычный JS?
              Можете привести примеры?

              • +7
                Я про опциональность типизации.

                Хотя, в теории, можете использовать этот забавный toolchain из StackOverflow :)

                Typescript to Haxe: https://github.com/jeremyfa/node-ts2hx
                Haxe to C++: http://old.haxe.org/doc/start/cpp
                C++ to LLVM: http://llvm.org/
                LLVM to ASM: https://github.com/kripken/emscripten

                Good luck =)
                • 0
                  Потрясающе! Я даже всерьёз задумался об этом.
                • 0
                  Вот сегодняшний кейс. Пишу на TypeScript, кода много, пишу на нормально типизированном языке, со всем современными фишками, при этом спокойно выбираю таргет. Всегда сидел на es3 таргете, потому что нужно было кое что для ie8 поддержать.
                  Скомпилил свои тесты из es3 в котором обычно сидел в es6, так протестить. Билжусь в один файл, никаких webPack и Babel нет.
                  Абсолютно идентичный код, просто много регулярок и много вызовов функций (парсер юзер агентов)
                  image
                  внимание на скорость в ms. Chrome 56.
                  • +1

                    Так у вас тут идет сравнение двух настроек Typescript, которые генерируют разный код.


                    Изначально топик был о том, чтобы неплохо использовать аннотации типа и в рантайме. Например, чтобы можно было добавить аннотацию типа items: Array<string> и код стал работать оптимальнее и быстрее. Этого пока, к сожалению, в движках нет.

                    • +1
                      Да, только я смотрю на то что он генерит. И он генерит примерно то что я бы сам написал. И на es6 он использует нативные классы. А в es3 сделает тоже самое через прототипы.
                  • +1
                    Вот я прямо сейчас запрашиваю у какого-то сервиса в ангуляре, он мне возвращает промис, я подцепляю then. В код этот не лез очень давно, что этот res собой представляет — массив? объект? что за свойства у него вообще?

                    SciGraph.getParents(nodeUri, 20, relationship)
                              .then(function (res) {
                    // блин, что же там мой сервис должен был возвращать
                     }
                    


                    Не типизировал, теперь пойду в дебаггер смотреть, что же там приходит. Был бы тип — я сразу в IDE бы обратился к нужным свойствам.
                    • 0
                      Прошу простить, плохо прочитал вопрос и подумал, что он про скорость разработки, а не скорость результирующего кода.
                • +3
                  Ну кстати в некоторых ситуациях он может быть быстрее.
                  JS хоть и безтиповый сам по себе, но внутри JS-движков (V8 в частности) типы есть. А степень оптимизации функций сильно зависит от разнообразия типом параметров, которые она может принимать.
                  • +1
                    Он и подталкивает. Советую посмотреть. Оно не про TS, а про JS. Но многое о чём там говорится проще писать на TS.



                    • 0

                      Код код полученный из ts будет не медленней аналогичного кода на js. Но, так как интерпретаторы js устроены так, что оптимизируют код, который часто исполняется и там где типы переменных не меняются, то получается что код ts в 100% случаев может быть оптимизирован интерпритатором. А вот про js код так строго сказать нельзя, смотря как он написан.
                      Так что можно сказать довольно уверенно, что на больших проектах ts даст прирост по скорости исполнения.

                      • 0
                        Что-то похожее умеет делать Google closure compiler. В нем если код хорошо увешан типами, то можно включить дополнительные оптимизации и компилятор выдаст сминифицированный код который на 5-15% меньше чем без этих опций. Это конечно не значит, что он будет выполняться быстрее, но размер самого js файла тоже важен.
                        • 0
                          Говоря о производительности, была надежда на Dart, пока Google не объявил об отказе от поддержки виртуальной машины. В тот же день я принял решение отказаться от Dart в пользу TypeScript, т.к. прочих преимуществ у Dart не было. Теперь остается надежда только на WebAssembly, но его релиз будет еще ох как нескоро. Так что на следующие пару лет TypeScript прочно занял место лидера статической типизации в фронт-енд разработке.
                          • 0
                            У WebAssembly нет, и как я понимаю, на планируется Garbage Collector, соответственно туда джаваскриптеры не прибегут.
                        • –1
                          Пока нету реальных 250K строк кода, смысла в TS нету, походу. JSDoc+инспекция кода+эпизодическая компиляция в closure compiler — это меньшая головная боль чем постоянная компиляция и подключений библиотек через одно место
                          • +5
                            1. Когда уже есть 250к строк кода, переписать будет довольно долго.
                            2. По опыту, TS полезен на проектах любого размера, поскольку позволяет крайне быстро рефакторить, что важно на ранних стадиях проэктировки, и поскольку напоминает про корнер кейсы и особенности JS.
                            • 0

                              TS не мешает сразу писать на нем, просто можно отключить проверки типов.

                            • –1
                              Вы пишете про typescript и говорите только про типизацию. Как-будто там ничего другого нет :) Вот тот же вытекающий type inference чего стоит. Много другого полезного (хотя в ES6 тоже вещей вкусных в своё время завезли).
                              • +1
                                а что type inference не относится к типизации?
                                • –4
                                  Можно я верну вам ваш вопрос в виде трех, раз уж он почти риторический. Что об этом в статье написано? Что у меня в комменте об этом написано? Что еще в комменте у меня написано?
                                  • 0
                                    Я не понял вашего ответа на вполне логичный вопрос dark_ruby.
                                    • –4
                                      Как печально-то, сочувствую. В качестве рецепта, попишите на С.
                                      • +1
                                        А я и ответ dark_ruby не понял, и этот ответ тоже.
                                        И на с, и на с++, и даже на с# писал, если что.
                              • +3
                                Как перетащить все на typescript? Перетаскиваем один модуль, перетаскиваем все остальное.
                                • 0
                                  У меня один небольшой вопросик к знатокам typescript. Есть такая директива module. Как я понял, она позволяет создавать один модуль из нескольких ts-файлов. В итоге, в пределах данного модуля я могу спокойно обращаться к классу, находящемуся в другом файле, не импортируя его. Компилятор хорошо понимает, что я хочу сделать. Но webpack — нет. Уже в браузере мне выдается сообщение об ошибке, что класс не найден. Кто-нибудь знает, как побороть данную проблему?
                                  • +1
                                    webpack не умеет в modules/namespaces ибо ts изначально транспайлился кучкой, ну т.е. все файлы в общем скоупе. Позже появились es6-модули, импорты которых завязаны на файлы, а не на неймспейсы/пакеты (имхо крайне неповоротливое решение, ибо почти во всех взрослых языках все на пакетах). Вебпак у нас работает именно с файлами-модулями, отсюда он и не может понять без прямого референса в каком из файлов лежит «добавка» к текущему модулю.
                                    Отсюда совет — либо не используйте вебпак для транспайлинга TS, либо не используйте modules/namespaces, учитывая, что даже офф-доки TS все на ES6-модулях.
                                    • 0

                                      Дело в том, что мы в проекте используем Typewriter для того, чтобы сгенерить типы данных Typescript по уже имеющимся типам C#. Так как Typewriter не умеет ссылаться на другой автосгенеринный тип данных автоматически, я это сделал следующим образом: все сгенерированные типы я экспортирую в одном файле all.ts и в шаблоне Typewriter я импортирую этот файл как: import * as Models from './all'. Думал, что как-то можно заюзать директиву module, но из ваших слов я понял, что это сделать не получится. От текущего решения я как-то не в восторге, поэтому надо искать что-то другое....

                                      • 0
                                        Просто добавьте еще один шаг сборки всей кучи нагенеренных классов в один js-файл с флагом генерации .d.ts по нему. У вас получится своего рода библиотечка из одного модуля вместе с декларацией типов, из который вы сможете удобно все нужное импортировать. Нам так коллеги с бэка генерят апи с джавы.
                                        • 0

                                          Это идея. Надо будет попробовать. Спасибо.

                                    • 0

                                      +1 к комментарию выше. Встроенные Typescript-модули были актуальны раньше, а сейчас уступают место стандартным JS-импортам. Все это неплохо описано на этой странице документации TS

                                      • 0

                                        Она же deprecated, нет?

                                        • 0

                                          См. мой коммент выше

                                      • +1
                                        Flow бы выбрал. Потому что он не компилятор.
                                      • –1
                                        При работе с TypeScript 1.8 для того, чтобы добавить новый файл объявлений, нужно установить отдельные npm-пакеты глобально, найти файлы объявлений для конкретной библиотеки и сохранить все файлы описаний библиотек в папке «typings». Честно говоря, решение это было не самое элегантное.

                                        Есть такой npm модуль, Typings, он дейтсвует по принципу npm — создаёться конфиг файл typings.json, в него заносяться зависимости и сами засовываються в папочку typings.
                                        ЗЫ практически все тайпинги можно найти тут
                                        • +2
                                          Это означает, что он не только поддерживает проверку типов, но и позволит работать с будущими возможностями ES6 и ES7.

                                          Время от времени вижу эти термины что они значат? ES6 — это старое название ES2015, ок. А что значит ES7?
                                          ES2016? Судя потому, что упоминается в контексте "будущих возможностей", то нет. ES2017? Все будущие спецификации? Все фичи, которые находятся на Stage 0 — 3? Что это?

                                          • –1

                                            Ещё ES2015 до конца не поддерживается в популярных браузерах и, кажется, в NodeJS, так, что, например, рассчитывать на оптимизацию хвостовой рекурсии в продакшене несколько опрометчиво.

                                          • 0

                                            Переводили на typescript с модулями и нормальными es6 импортами? Мы в проекте столкнулись с тем, что перевести на typescript без модулей не сложно, берёшь и потихонечку переписываешь. А вот теперь перевести на модули и импорты проблематично, потому что половина кодовой базы уже на typescript без модулей и невозможно нормально ссылаться из новых модульных файлов в старые не модульные. Думаем как-то автоматически сгенерировать импорты, хочется использовать webpack. Наверное, сразу переводить на модульный typescript было бы проще.

                                            • 0
                                              Больше года уже использую Typescript в связке с create-react-app и кастомным react-scripts-typescript-scss на проектах любого размера. Идеальная поддержка в VS Code, возвращаться на Babel нет никакого желания)
                                              • 0

                                                Интересно узнать сколько багов было найдено и какое покрытие тестами было до перехода.

                                                • 0
                                                  и сколько багов появилось после перехода
                                                • 0
                                                  3 года назад переводил свой проект (тогда ещё около 10к строк было) на тайпскрипт. Ушло несколько недель, но разработка после этого — сказка. Не даёт сделать совсем глупые ошибки, следит за типами, и в случае чего, выдаёт предупреждения.

                                                  На чистом JS такие ошибки только в рантайме отлавливать, что долго и тяжело.
                                                  • 0

                                                    Мне тоже Flow понравился, только я использую grunt-flow, он позволяет избавиться от кучи глупых опечаток и, на первый взгляд, невидимых проблем.

                                                    • 0
                                                      Dart или Kotlin не рассматривали? За первым Google, за вторым JetBrains — тоже неслабые конкуренты.
                                                      • +1
                                                        Google — GWT помните? А Kotlin пока очень экзотичен, спецов под него не найдёшь, и если помет — вы застряли с приложением на нем написанным.
                                                        У TS тут два основных преимущества:
                                                        — готовые спецы уже есть, да и прочие хорошие программисты JS легко осваивают, ибо суперсет;
                                                        — в самом худшем случае «TS помер», у вас на руках остался странспиленный JS, который легко читается человеком.
                                                      • +1

                                                        Я выбираю Flow, т.к. волен выбирать вкусные babel-плагины.

                                                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                      Самое читаемое