Язык программирования TypeScript от Microsoft привносит многие преимущества статической типизации в JavaScript. Несмотря на то, что он не проверяет типы во время исполнения, он позволяет производить более точный статический анализ, повышает безопасность и открывает возможности для лучшей интеграции с IDE. Код на TypeScript обычно транспилируется в стандартный JavaScript, который выполняется в браузерах или Node.js. Учитывая привлекательность TypeScript, не удивительно, что его популярность быстро растёт.


Конечно, использование нестандартного диалекта языка не лишено объективных недостатков. Использование TypeScript в вашем проекте потребует дополнительного шага при сборке проекта, исключается возможность использования широкого набора инструментов, которые рассчитаны только на JavaScript. Так же, всем членам команды придется изучить нестандартные для JS функции. Так же, принимая во внимание скорость развития JavaScript, есть некоторый риск получить зависимость от нестандартного функционала. Разработчики TypeScript спроектировали язык с учётом некоторых потенциальных проблем, но, тем не менее, это не "ванильный" JavaScript.


К счастью, JavaScript разработчики могут получить некоторые из преимуществ используя привычный инструмент. В версии TypeScript 2.3, которая вышла в Апреле 2017 года, появилась поддержка анализа обычного JavaScript кода с указанием типов в комментариях. Вы можете использовать JSDoc подобный синтаксис для описания сигнатуры функций и добавления информации о типах. Инструменты TypeScript читают аннотации в комментариях и используют их практически так же как и в собственной системе типов.


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


Рабочий пример


Для того чтоб включить анализ JavaScript кода с помощью TypeScript просто добавьте комментарий с текстом @ts-check в начало файла. Потом вы можете добавить аннотации с указанием типов в пределах этого файла. Следующий пример показывает описание сигнатуры функции с двумя параметрами и определённым типом возвращаемого значения.


// @ts-check

/**
 * @param {number} a
 * @param {number} b
 * @return {number}
 */
function example(a, b) {
    return a + b;
}

Visual Studio Code, который поддерживает TypeScript из коробки, автоматически находит такие комментарии и включает режим проверки. Это не потребует абсолютно никакой настройки. Вам даже не надо создавать конфигурационный файл для TypeScript. Просто добавьте комментарии в любой JavaScript код. Если вы после этого попробуете вызвать функцию с неправильными аргументами, редактор покажет предупреждение.



Редактор так же будет использовать аннотации чтоб улучшить другие функции, такие как автодополнение. Кроме того, информация о типах успешно используется между файлами благодаря тому, что TypeScript понимает ES6 импорты и require в Node.js.


Вы так же можете использовать аннотации для указания структуры обычного объекта. Это может оказаться полезным когда вы хотите получить автодополнение свойств объекта и проверку их наличия для JSON данных полученных от какого-либо API. Следующий пример показывает как вы можете описать структуру объекта используя аннотации.


/**
 * @typedef {Object} Issue
 * @property {string} url
 * @property {string} repository_url
 * @property {id} number
 * @property {string} title
 * @property {string} state
 * @property {bool} open
 */

const url = "https://api.github.com/repos/microsoft/typescript/issues";

(async () => {
  let response = await got(url, {json: true});

  /** @type {Issue[]} */
  let issues = response.body;
  for (let issue of issues)
    console.log(issue.title);
})();

В этом примере используется специальная аннотация @typedef для определения типа объекта Issue. Далее в функции получения данных, мы указываем с помощью @type что полученный ответ представляет собой массив объектов Issue.


Вы можете найти больше примеров использования аннотаций в TypeScript wiki.


Поддержка библиотек


TypeScript уже имеет указания типов для стандартной библиотеки Node.js, так что вы можете пользоваться проверками и дополнением практически всех её функций из коробки. Некоторые сторонние библиотеки также имеют файл с указанием типов(как правило — это файл с расширением d.ts) в своих npm пакетах. Добавление @ts-check для вашего проекта будет так же учитывать типы импортированных из таких библиотек функций и объектов.



Заключение


Весь прошлый год я старался упростить свои инструменты JavaScript разработки и уйти от нарастающей сложности и избыточности, поражающей современную веб разработку. Использование аннотаций в комментариях неплохо позволяет придерживаться этой стратегии. Я получаю преимущества TypeScript не добавляя лишний шаг при сборке проекта во время разработки. Это похоже на использование TypeScript в качестве умного линтера, а не языка программирования. Мне даже не надо добавлять его в зависимости своего проекта. Я просто включаю проверку типов как простую функцию редактора и это позволяет мне лучше писать код.

Комментарии (28)


  1. k12th
    13.10.2017 14:30

    Почему-то в WebStorm у меня эта история с @ts-check не завелась: TypeScript не ругается и IDE не подчеркивает. Хотя если просто описать интерфейсы в отдельном .ts и прописывать типы в js-doc, то интеллисенс здорово умнеет.


  1. hudson
    13.10.2017 15:34

    Спасибо за публикацию! Как раз начал облагораживать legacy код на JS, планирую перевести всю кодовую базу на TS — эта функция поможет подготовить старый код к портированию.


  1. stardust_kid
    13.10.2017 17:05
    -1

    А нужен ли он вообще?
    image


    1. wert_lex
      13.10.2017 18:10
      +3

      Вопрос в размере кодовой базы. Если всё входит в одну среднюю голову одного среднего программиста — то проблем нет. Проблемы начинаются тогда, когда проект растёт.


    1. impwx
      13.10.2017 18:59
      +1

      Typescript для веб-разработчика — это как каска на стройке. Если рабочий отказывается ее носить, потому что «ее надевать долго» или «это у всяких дураков кирпичи на голову падают», его сложно воспринимать всерьез.


      1. Aingis
        15.10.2017 14:27
        +1

        Ещё ни один человек, в том числе на Хабре, не смог привести (реальный, не надуманный как в публикации) пример, когда отсутствие строгой типизации привело бы к реальным багам. А вот как раз с обратными ситуациями я пару раз сталкивался.

        Баги ловит не типизация, а тесты. Надеяться, что «введём типизацию и избавимся от багов» может только крайне наивный и далёкий от разработки человек. Как правило, баги возникают в логике, а не в том что что-то не туда привелось. Не говоря уж о том, что любой разработчик старше джуна должен быть знаком с языком и не писать глупостей вроде [] == false.


        1. impwx
          15.10.2017 16:06

          Статическая строгая типизация не заменяет тесты, однако она позволяет существенно сократить их количество. Кроме того, она частично заменяет документацию, существенно упрощает и повышает качество подсказок в IDE, рефакторинга и оптимизаций. Отказываться от этих преимуществ есть смысл только в том случае, если весь исходный код программы влезает на один экран.

          Баги, которые реально встречаются в коде без указания типов — это когда в функцию, принимающую аргумент типа A, передают значение типа B. Повсеместный пример в JS — сторонняя библиотека, принимающая при инициализации объект-конфиг. Как быть уверенным, что в каком-нибудь свойстве не закралась опечатка? Что не передал строку, когда нужно было массив с одной строкой? Каждый раз сверяться с документацией на сайте, если она вообще есть?

          Если претит сама идея писать на каком-то новом транслируемом языке, то можно использовать Flow и описывать типы в комментариях. Код остается чистым Javascript'ом, однако все равно проверяется статически. Проверки у Flow слегка получше, а тулинг слегка похуже, поэтому выбор между ними — сугубо дело вкуса.

          Вот пример вполне реального бага, который возник из-за нестрогой типизации:

          if(this.flag) {
              this.doStuff();
          }
          

          Оказалось, что flag объявили не как свойство, а как метод (забыли модификатор get). Условие срабатывало всегда, потому что функция неявно приводилась к виду truthy. Любопытно, что в этом случае даже Typescript не спас — такое неявное приведение в нем допустимо, вероятно ради совместимости с идиомами в Javascript. Надеюсь, в будущих версиях позволят это запрещать специальным флагом компилятора.

          С удовольствием послушаю историю про то, как наличие строгой типизации вызвало баг!


          1. Aingis
            15.10.2017 16:22

            Статическая строгая типизация не заменяет тесты, однако она позволяет существенно сократить их количество.
            Если вы разрабатываете не популярную библиотеку и пишите тесты на проверку типов, то вы что-то делаете не так.
            Кроме того, она частично заменяет документацию, существенно упрощает и повышает качество подсказок в IDE, рефакторинга и оптимизаций.
            JSDoc — стандарт де факто — делает то же самое. Рефакторинг — довольно редкий кейс, сомнительно что накладные расходы на типы окупает что-то.
            Баги, которые реально встречаются в коде без указания типов — это когда в функцию, принимающую аргумент типа A, передают значение типа B. Повсеместный пример в JS — сторонняя библиотека, принимающая при инициализации объект-конфиг. Как быть уверенным, что в каком-нибудь свойстве не закралась опечатка? Что не передал строку, когда нужно было массив с одной строкой? Каждый раз сверяться с документацией на сайте, если она вообще есть?
            Только что говорили о тестах, уже забыли? TDD это решает. В отличие от типизации польза от тестов доказана.
            Вот пример вполне реального бага, который возник из-за нестрогой типизации… Любопытно, что в этом случае даже Typescript не спас…
            Забавный пример, но отношение к типам тут натянуто.
            С удовольствием послушаю историю про то, как наличие строгой типизации вызвало баг!
            Банально, из-за навязывания строгого сравнения коллега поменял проверку в последний момент на код-ревью, и перестало работать сравнение вида 2 == '2', где последнее — это значение флага, приходящее с бэкенда.

            Про то, что это вопрос вкуса, я согласен. Но и согласен с Крокфордом, что та многословность, которую несёт Typescript не окупает потенциальную выгоду. Если где-то куча джунов пишут говнокод, то TS всё равно не спасёт от говнокода.


            1. impwx
              15.10.2017 17:18

              JSDoc — стандарт де факто — делает то же самое.
              JSDoc + Flow тоже хороший вариант. А вот если использовать только один JSDoc, то все проверки оказываются на честном слове.

              Только что говорили о тестах, уже забыли?
              Сколько кода потребуется написать, чтобы выявить ошибку в этой строчке?
              $('.dropdown').selectize({ max_items: 3 });
              
              Вместо этого можно одной командой установить @types/selectize и компилятор сразу же скажет — свойство должно называться maxItems. По сути, это те же тесты, только их за вас уже написали авторы библиотеки или участники сообщества.

              перестало работать сравнение вида 2 == '2'
              Это же контрпример :) Бага в вашем случае была в том, что сервер присылал строку вместо числа, а строгая проверка позволила ее выявить и исправить.


              1. Aingis
                15.10.2017 17:55

                А вот если использовать только один JSDoc, то все проверки оказываются на честном слове.
                Да всё держится на честном слове, если так рассуждать. Поэтому и придумали всякие техники вроде код-ревью и TDD.
                Сколько кода потребуется написать, чтобы выявить ошибку в этой строчке?
                Вы тесты не пишете что-ли? Постоянно про них забываете. Первый же тест выявит баг. Уже надоело повторять. Впрочем, учитывая то, что пример на jQuery, удивляться не приходится.
                Бага в вашем случае была в том, что сервер присылал строку вместо числа…
                Сваливать ошибки на других — это приятно, конечно, — все в грязи, один я в белом, — но профессионалы так не делают. И с чего вы взяли что это ошибка? Раньше работало же. Вам в ответ могут сказать, что какие проблемы, Javascript же умеет преобразовывать типы, и ответить вам будет нечего.

                Суть в том, что вы не можете отвечать за данные, которые приходят извне. Поменяет сервис протокол — и что, всё переписывать что-ли? Или будете утверждать, что это фича? Сервис может от вас вообще никак не зависеть.


                1. impwx
                  15.10.2017 19:43

                  Да всё держится на честном слове, если так рассуждать.
                  Отнюдь. Если ошибка в TS, она поймается на этапе сборки, а в JS — только при запуске. Понимаете разницу?

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

                  Javascript же умеет преобразовывать типы, и ответить вам будет нечего
                  Есть целый сайт, посвященный ответу на вопрос «почему неявное приведение зло»: WTF JS. Если собеседник настаивает на обратном, пусть объяснит пару примеров.

                  Поменяет сервис протокол — и что, всё переписывать что-ли? Или будете утверждать, что это фича?
                  Вот пример: вы получаете от API стоимость товара, прибавляете наценку и списываете деньги с пользователя. Вдруг сервис прислал строку вместо числа — и вместо 10 + 2 = 12 вы списали '10' + 2 = '102' рубля.

                  Невозможность такой ситуации — это ключевая фича. Она называется Fail-fast. Быть сторонником тестов и при этом слепо доверять приходящим извне данным — это мощно!


                  1. Aingis
                    15.10.2017 23:17

                    Отнюдь. Если ошибка в TS, она поймается на этапе сборки, а в JS — только при запуске. Понимаете разницу?
                    А если ошибка в ДНК алгоритме, то она будет поймана в самый неподходящий момент. И это 99% ошибок. Вы смотрите на частности и за деревьями не видите леса. Тесты и прочее уменьшают это число на 20–80% (в зависимости от организации процесса). TS от силы на 1%, вот и вся разница.
                    Есть целый сайт, посвященный ответу на вопрос «почему неявное приведение зло».
                    Это сайт о том, что не надо писать говнокод надо всё-таки знать язык на котором пишешь. Никто в здравом уме не будет делать проверки вида [] == false или [] == ![]. Для этого есть строгое сравнение.
                    Вдруг сервис прислал строку вместо числа — и вместо 10 + 2 = 12 вы списали '10' + 2 = '102' рубля.
                    Вы опять аргументируете говнокодом. Если у вас разработчики не учитывают такое, то они и всё-равно напишут говнокод. Например, алгоритм со сложностью O(n2) вместо O(1). И что, спасёт вас Typescript?
                    Быть сторонником тестов и при этом слепо доверять приходящим извне данным — это мощно!
                    О, пошла демагогия. Когда очень хочется возразить, а серьёзных аргументов нет, начинаются приписывания оппонентам выдуманные убеждений.

                    А суть в том что приведение типов — это фича. Что проще 2 == '2' или 2 === Number('2')? Ответ очевиден. А если нет разницы, зачем усложнять код? Все аргументы сводятся к одному: «я говнокодер не знаю JS и не хочу думать». Убогая позиция.


                    1. Druu
                      16.10.2017 06:20

                      > Что проще 2 == '2' или 2 === Number('2')?

                      Второй вариант проще, конечно же. Вы же эту очевидность имели в виду?

                      > Вы смотрите на частности и за деревьями не видите леса. Тесты и прочее уменьшают это число на 20–80% (в зависимости от организации процесса). TS от силы на 1%, вот и вся разница.

                      Типизация нужна не для того, чтобы ловить ошибки, а чтобы ловить их _рано_. Чем раньше обнаружена ошибка — тем быстрее ее можно исправить. В случае с типизацией огромное количество ошибок исправляется просто мгновенно — за счет рабочего автокомплита, например. Если на исправление ошибки с тестами вы тратите условные 5-10сек, а с тс — 0сек, то тысяча-другая таких ошибок уже экономит время порядка часов, а поскольку возникают такие ошибки практически в каждой строке (а часто — по несколько на строку), то вы поняли. И это не учитывается время на написание тестов.

                      Ну и не надо забывать, что стоимость использования тс — нулевая. А если можно бесплатно получить некоторый бонус, то какой смысл от него отказываться, каким бы маленьким он ни был?


                      1. Aingis
                        16.10.2017 12:11

                        Второй вариант проще, конечно же. Вы же эту очевидность имели в виду?
                        Facepalm
                        Типизация нужна не для того, чтобы ловить ошибки, а чтобы ловить их _рано_. Чем раньше обнаружена ошибка — тем быстрее ее можно исправить.
                        Почему вы всё время забываете про тесты? Вы их никогда не писали что-ли? Именно они ловят ошибки рано, и куда больше ошибок чем копейки от типизации (которые никто и не допустит, по-хорошему, а если допустит, то типизация что мёртвому припарки).
                        Если на исправление ошибки с тестами вы тратите условные 5-10сек, а с тс — 0сек
                        Лол, что?! Только не надо прямого вранья! У вас мгновенная компиляция что-ли? Нет ничего хуже чем поддерживать проект с компиляцией в несколько минут.
                        Ну и не надо забывать, что стоимость использования тс — нулевая.
                        Опять враньё. Вы тратите время на написание громоздких конструкций типов. Вы тратите время на компиляцию. Вы ограничиваете себя в поиске разработчиков. У вас вендор-лок, в конце концов. Это далеко не нулевая стоимость, и она не стоит того, чтобы решать уже решённые проблемы.

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


                        1. stardust_kid
                          16.10.2017 12:36
                          -2

                          Ребятам просто нужен новый Coffee Script. Поиграться пару лет, а потом обнаружить, у себя пару мегабайтов эзотерического устаревшего кода в базе. Зато строгая типизация, лол. Страшная опасность преобразовать массив в строку предотвращена.


                        1. Druu
                          16.10.2017 14:29
                          +2

                          > Почему вы всё время забываете про тесты? Вы их никогда не писали что-ли?

                          Еще раз, типизация для того, чтобы ловить ошибки _рано_. Да, тесты тоже ошибку поймают — но очень, очень поздно.

                          > Лол, что?! Только не надо прямого вранья! У вас мгновенная компиляция что-ли?

                          У меня тайпчек в ИДЕ. Да, де-факто мгновенный.

                          > Опять враньё. Вы тратите время на написание громоздких конструкций типов.

                          Нет, не трачу. Описания типов значительно более компактны, чем тот же jsdoc. При этом более выразительны. Так что на практике я _экономлю_ на том, что пишу типы вместо использования более громоздких форматов документации.

                          > У вас вендор-лок, в конце концов.

                          Apache license, какой еще вендор-лок?

                          > Вы тратите время на компиляцию.

                          Это было бы аргументом только в том случае, если бы и так не было всякого тулчейна вроде бабелов и вебпаков. Да и то — кого волнует секунда-две на компиляцию? Никого.

                          > Почему вы постоянно игнорируете сильные аргументы и держитесь за свои слабые, не подтверждённые, утверждения как за мамину ручку?

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

                          Это уж не говоря о том, что любой рефакторинг без типов превращается в ад (а в вебе рефакторинг происходит постоянно).


                          1. Aingis
                            16.10.2017 18:10
                            +1

                            У меня тайпчек в ИДЕ. Да, де-факто мгновенный.
                            Это фича IDE, а не Typescript. IDE может так и без TS.
                            Нет, не трачу. Описания типов значительно более компактны, чем тот же jsdoc.
                            Опять выдумаете. Кроме того, JSDoc вы можете написать потом, с устоявшимся кодом, а типы вы должны писать постоянно, тратя куда больше времени попусту.
                            Это было бы аргументом только в том случае, если бы и так не было всякого тулчейна вроде бабелов и вебпаков.
                            Тулчейн опционален, вы вообще можете написать
                            <script type="module"> и разрабатывать прямо в браузере со всеми модулями, ES2016+ и красивыми тестировщицами, а c TS опять же привязываетесь к компиляции.
                            Да и то — кого волнует секунда-две на компиляцию? Никого.
                            Если бы всё так было просто и быстро, но вы ещё добавляете лишнее время компиляции. Это уже не секунда-другая.
                            Наличие полноценного автокомплита, компактная документация, быстрое обнаружение ошибок — это вполне себе подтвержденные утверждения, в истинности которых может любой убедиться на практике.
                            1. Опять путаете фичи IDE.
                            2. Вы не привели ссылок на академические исследования.
                            Это уж не говоря о том, что любой рефакторинг без типов превращается в ад (а в вебе рефакторинг происходит постоянно).
                            Синдром утёнка.


                            1. Druu
                              17.10.2017 14:13

                              > Это фича IDE, а не Typescript. IDE может так и без TS.

                              Нет, не может. Чтобы чекнуть язык, должна быть система типов.

                              > Опять выдумаете.

                              Нет, не выдумываю. Просто сравните два варианта описания на примере. Кроме того, типы всегда актуальны, в отличии от jsdoc.

                              > Тулчейн опционален, вы вообще можете написать и разрабатывать прямо в браузере со всеми модулями, ES2016+ и красивыми тестировщицами

                              Чисто теоретически — могу, но практически — нет, не могу.

                              > Если бы всё так было просто и быстро, но вы ещё добавляете лишнее время компиляции.

                              Так тем более. Если было 0 сек. компиляции, а стало секунда-две — это и так не влияет ни на что существенно. А если было 20 сек, а стало 21-22 — то тем более плевать.

                              > 1. Опять путаете фичи IDE.

                              Эти фичи ИДЕ невозможны без типизации. Отказываетесь от типизации — отказываетесь от фич.

                              > Синдром утёнка.

                              Нет, это факт. Например, вы поменяли поля в некотором объекте, как без типов определить все места использования объекта и поправить обращения?

                              > 2. Вы не привели ссылок на академические исследования.

                              Исследования чего? Проверку какого именно тезиса вы хотите увидеть?


        1. k12th
          16.10.2017 02:03

          Я с вами спорить не буду, но все-таки свои пять копеек вставлю, вдруг кто-то прочтет и задумается.


          Я вот тоже примерно так раньше рассуждал — сдалась мне ваша типизация, [] == false, лол, «белки истерички.jpg». Очевидно, явная типизация от багов в логике не спасает, против этого только тесты. Зато она спасает от лишней нагрузки мою голову, которую я могу приложить на написание ну хоть тех же тестов.
          Все дело в том, что явная типизация — это как документация, в которую не надо лезть. Перепутал порядок аргументов? опечатался в названии метода? Не помнишь, принимает либа число или строку, массив или словарь? Вернул не то значение из функции? Все это видно сразу прямо в IDE, без выпадения из потока на время запуска тестов и сборку фронтендом.


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


          Теперь что касательно js-doc. Это бы работало, если бы это был синтаксически зафиксированный стандарт. На деле кому-то пофиг, кто-то не в курсе, что IDE понимает jsdoc, кто-то упарывается каким-то кривым docco или еще какой дрянью, кто-то пишет под closure compiler и у них своя атмосфэра, кто-то пишет в VS, которая всего года три назад понимала только свой формат комментов, а комменты все стерпят, вот и пишут кто во что горазд, а потом интеллисенс не работает. Явная типизация берет на себя роль зафиксированного, понимаемого всеми сторонами синтаксиса документации.


        1. Nipheris
          16.10.2017 08:39

          Конечно отсутствие строгой типизации не приводит к реальным багам. Отсутствие строгой типизации ПОЗВОЛЯЕТ программисту добавлять новые баги.

          Во-первых, я думаю вы понимаете, что если у вас есть JSDoc и тесты, то статическая типизация у вас УЖЕ есть, только неявно и контроллируется она вручную. То, что вы умеете и можете это делать средставами, удобными именно вам, не значит что ваше решение объективно лучшее.

          Во-вторых, ошибки на этапе компиляции — это, пожалуй, объективно полезно. Да, вы можете сказать, что тесты вы запускаете также в процессе сборки проекта и можно сказать что это эквивалентное средство. Но если я могу достичь аналогичного результата с помощью информации, которая обрабатывается И компиляторо И программистом одинаково (синтаксис строго-типизированного языка), зачем мне эту информацию разделять между документацией для разоработчика (JSDoc) и тестами?

          В третьих, я думаю тесты — это замечательная вещь, которой можно и нужно покрыть всё, что НЕ УДАЛОСЬ покрыть более продвинутыми проверками, такими как типизация (и прочие виды проверок в compile-time). Иными словами, я считаю мы должны идти от тестов к более специализированным и строгим средствам верификации, а не наоборот.

          Давать программисту сначала свободу в виде динамической типизации всех переменных и значений, а потом в большинстве случаев эту свободу «забирать», ограничивая тестами РЕАЛЬНЫЕ ветви исполнения кода и РЕАЛЬНЫЕ типы данных, которые код может обработать — это неэффективно. А в реальном коде именно так и будет происходить — не так уже часто нужен действительно «полностью динамический» тип (top-type или any).

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


          1. Aingis
            16.10.2017 14:03

            Ещё ни один человек, в том числе на Хабре, не смог привести (реальный, не надуманный как в публикации) пример, когда отсутствие строгой типизации привело бы к реальным багам.
            Конечно отсутствие строгой типизации не приводит к реальным багам. Отсутствие строгой типизации ПОЗВОЛЯЕТ программисту добавлять новые баги.
            Весьма убедительно. Очень наглядный пример. То-то никто так и не смог доказать явную пользу типизации больше статистической погрешности. (В отличие от код-ревью, тестов и так далее.)


    1. k12th
      13.10.2017 20:41

      Крокфорд пользуется огромным авторитетом в сообществе, но я как вспомню его ненастраиваемый jslint c куцым набором правил, половина из которых — субъективная вкусовщина...


      1. stardust_kid
        16.10.2017 12:34

        Вы лучше его Good Parts вспомните. А jslint был хорош в свое время, но прогресс не стоит на месте.


        1. k12th
          16.10.2017 12:38

          Good Parts мне понравилась больше, чем jslint, но тоже не целиком.


  1. Focushift
    13.10.2017 23:36

    Можно чуть подробнее насчет использования файлов d.ts с обычным js кодом?


  1. Nikelandjelo
    14.10.2017 06:07

    Ура, переизобрели closure compiler который уже лет 10 умеет это делать. Жалко, конечно что closure так и не взлетел. Он и статическую типизацию поддерживает и по степени обфускации будет на шаг вперед всех остальных текущих библиотек. К сожаление отсутствует хорошая интеграция с npm и остальными популярными тулами.


    1. k12th
      14.10.2017 12:48

      Не взлетел, потому что барахло по объективным причинам. Тайп-чекинг, ЕМНИП, там очень выборочный; с IDE не интегрируется; аннотации не совместимы с js-doc; сжатие… ну когда-то лидировал, сейчас примерно на равных с uglify. Плюс они ухитрились сделать неудобный cli.


    1. Druu
      16.10.2017 06:27

      > Ура, переизобрели closure compiler который уже лет 10 умеет это делать. Жалко, конечно что closure так и не взлетел.

      В closure compiler очень слабая система типов, по назначению это оптимизатор-обфускатор. В качестве тайпчекера js на практике он применяться не может (разве что в ряде оооочень сильно ограниченных кейсов). В общем-то тут ничего странного и нет — когда писали closure compiler, то нормально типизировать динамические языки еще не умели, это результат научных работ последних лет 3-4.