[Перевод] Цена TypeScript

В 2017–2019 годах можно было наблюдать серьёзный рост TypeScript. Происходило это по вполне понятным причинам. В этом языке есть много хорошего. Почти половина респондентов исследования State of JavaScript 2018 года уже пробовали TypeScript и собираются писать на нём в будущем. TypeScript весьма популярен, но стоит ли использовать его в крупномасштабных программных проектах?

ocj1ardtsbjl5njab5ymmmug69u.jpeg

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

О росте TypeScript


TypeScript — это один из самых быстрорастущих языков. В настоящее время это — ведущий язык из тех, которые компилируются в JavaScript. Вот данные по TypeScript из Google Trends.

cd9106ec65b854ea581b3da83a347f08.png


Данные Google Trends за 2014–2019 годы по динамике популярности TypeScript

Ниже показаны сведения с GitHub, отражающие интерес программистов к работам по развитию различных языков программирования.

fd08cf061c5f6bdfe1f582c41cb68e59.png


Данные GitHub по росту языков программирования с точки зрения числа контрибуторов

Выше представлены весьма впечатляющие показатели, указывающие на рост популярности TypeScript, которые нельзя недооценивать. Но при этом надо отметить, что TS ещё далёк от того, чтобы его можно было бы признать ведущим языком экосистемы JavaScript. Если экосистему JavaScript сравнить с океаном, то TypeScript будет большой волной в этом океане. Вот сравнение JavaScript (красная линия) и TypeScript (синяя линия) по данным Google Trends.

ec0eeb0b53de716dadebe716551e8a85.png


Данные Google Trends за 2014–2018 годы по динамике популярности JavaScript и TypeScript

А вот сведения с GitHub о ведущих языках программирования, использованных при создании репозиториев в 2008–2018 годах.

fc9810ca19557142f5a3919788703bfe.png


Данные GitHub по количеству репозиториев, созданных с использованием различных языков программирования

Можно заметить, что, по числу репозиториев, TypeScript не входит в первую пятёрку языков.

При этом надо отметить, что в 2018 году произошёл переломный момент в истории TypeScript, и в 2019 году этот язык будет использоваться во множестве реальных проектов. Если вы являетесь JavaScript-разработчиком, то у вас, в таких условиях, просто не будет выбора. Решение об использовании TypeScript в некоем проекте, над которым вам придётся работать, уже, без учёта вашего мнения, будет принято. При этом не нужно бояться изучать и использовать TypeScript.

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

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

Предыстория


Я пришёл в JavaScript из мира статически типизированных языков — таких, как C/C++ и Java. В первое время мне было тяжело приспособиться к динамической типизации, принятой в JavaScript, но как только я к ней привык, я почувствовал себя человеком, который дошёл до выхода длинного тёмного туннеля и увидел свет. У статической типизации немало позитивных черт, но то же самое можно сказать и о динамической типизации.

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

В 2018 можно было наблюдать взлёт децентрализованных приложений. В большинстве таких приложений использовались смарт-контракты и опенсорсные решения. При разработке приложений для интернета ценностей (Internet of value) ошибки в программах могут стоить пользователям денег. Сейчас, как никогда, важно писать надёжный код. Так как подобные проекты обычно бывают опенсорсными, я подумал, что то, что мы используем в разработке TypeScript — это хорошо, так как благодаря этому другим TypeScript-командам будет легче работать с нашими решениями, и, в то же время, благодаря этому обеспечивается совместимость нашего кода с проектами, в которых используется JavaScript.

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

Сильные стороны TypeScript


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

Статическая типизация может быть весьма полезной в том плане, что она помогает документировать функции, делает код понятнее и уменьшает когнитивную перегрузку программиста. Например, я обычно нахожу систему типов Haskell помогающей работать, не требующей излишних затрат времени и сил, удобной, ненавязчивой. Но иногда даже гибкая система типов Haskell и его типы высших родов (higher-kinded type) мешают работать. Попытайтесь, например, типизировать трансдьюсер средствами Haskell или TypeScript. Сделать это непросто, и, возможно, результат окажется немного хуже чем его нетипизированный эквивалент.

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

TypeScript поддерживает интерфейсы, которые подходят для повторного использования (в отличие от встроенных описаний типов). Интерфейсы можно по-разному применять для аннотирования API и сигнатур функций. У одного интерфейса может быть много реализаций. Интерфейсы — это одна из лучших возможностей TypeScript и мне хотелось бы, чтобы нечто подобное появилось бы в обычном JavaScript.

Одна из сильнейших сторон TypeScript заключается в его инструментарии. Например, использование подходящего редактора (вроде Atom или Visual Studio Code), для которого созданы качественные TS-плагины, даёт в распоряжение разработчика лучшие из существующих в экосистеме JavaScript инструменты. Разработчикам других плагинов стоит изучить TS-плагины и подумать над тем, как, используя идеи, заложенные в них, они могут улучшить свои разработки.

Анализ эффективности TypeScript


Сейчас я собираюсь оценить TypeScript по нескольким показателям, выставляя оценки в диапазоне от -10 до 10. Это поможет вам лучше понять то, насколько хорошее (или плохое) влияние может оказать TypeScript на большие проекты.

Если оценка по показателю превышает 0 — это говорит о позитивном воздействии TypeScript на проект. Если оценка меньше 0 — это указывает на негативное воздействие. Значение оценки в 3–5 баллов говорит о достаточно сильном воздействии. 2 балла указывают на среднее воздействие. 1 балл — сравнительно слабое воздействие.

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

Все проекты, которые я анализировал, выставляя оценки, содержали более 50 тысяч строк кода. Они явились плодом работы нескольких программистов в течение нескольких месяцев. Один из этих проектов основан на Angular 2, в нём использовался TypeScript. Он сравнивался с похожим проектом, написанным с применением Angular 1 и обычного JavaScript. Все остальные проекты созданы на базе React и Node с применением TypeScript. Они сравнивались с аналогичными проектами, в которых использовался обычный JavaScript. Некоторые показатели, наподобие плотности ошибок (bug density), были оценены лишь приблизительно. Все команды, работавшие над проектами, состояли из опытных и начинающих TypeScript-разработчиков. У всех членов таких команд была возможность взаимодействия с более опытными наставниками, которые помогали им адаптироваться в сфере TypeScript-разработки.

Объективные данные, которыми я располагаю, за счёт небольшого объёма выборки, слишком разнородны, в них слишком много шума, поэтому на их основе нельзя вынести какие-то определённые объективные суждения, которые можно было бы выносить, опираясь на достаточно точные цифры и не рискуя слишком сильно ошибиться. Один проект на JavaScript продемонстрировал плотность ошибок, попавших в продакшн, на 41% меньше, чем сравнимый проект на TypeScript. В другом сравнении проект на TypeScript показал на 4% меньшую плотность ошибок, чем в сравнимом проекте на JavaScript. В данном случае очевидно то, что на число ошибок, добравшихся до стадии выпуска продукта, гораздо сильнее влияет не использование в проекте TypeScript, а наличие или отсутствие других мер по обеспечению качества кода. Это искажает показатели до такой степени, что пользоваться ими становится невозможно.

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

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

68055a359a10869d2a7512f7ddb30fc2.png


Анализ эффективности TypeScript

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

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

Рассмотрим показатели, приведённые на схеме.

▍Инструменты разработчика (Developer Tooling)


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

Большинство защитников TypeScript, как кажется, не очень хорошо понимают то, с чем именно конкурирует TypeScript. Речь идёт о том, что выбор инструментария — это не принятие решения о том, нужно ли использовать TypeScript или JavaScript без каких-либо вспомогательных инструментов. Речь идёт о выборе между TypeScript и всей богатой экосистемой инструментов для JavaScript-разработки. Средства автозавершения кода и обнаружения ошибок для обычного JavaScript дают 80–90% того, что обычно считают сильными сторонами TypeScript. Происходит это, например, при использовании средств для автозавершения кода, инструментов для вывода типов и линтеров. При использовании системы вывода типов и при применении параметров функций по умолчанию, появившихся в ES6, в распоряжении разработчика оказываются подсказки, весьма напоминающие те, которые доступны при работе над TypeScript-кодом с аннотациями типов.

32b15d614c65904297e3ec446c9c78e1.png


Пример автозавершения обычного JS-кода с выводом типов

Честно говоря, если вы используете для предоставления подсказок по типам параметры по умолчанию, то вам совершенно не нужно делать аннотации TypeScript-кода. Это — отличный приём, позволяющий сократить количество вспомогательных синтаксических конструкций, которые являются одним из минусов TypeScript.

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

▍Документирование API (API Documentation)


Ещё одно серьёзное преимущество TypeScript — это более качественное документирование API. Фактически, можно говорить о том, что документация к API всегда соответствует состоянию исходного кода. Документацию можно даже генерировать на основании TypeScript-кода. По этому показателю TypeScript тоже можно было бы поставить более высокую оценку — если бы, программируя на JavaScript, нельзя было бы пользоваться чем-то вроде JSDoc, Tern.js и множеством средств для генерирования документации. Лично я — не фанат JSDoc, поэтому TypeScript в моём анализе по этому показателю получает достаточно высокую оценку.

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

▍Типобезопасность (Type Safety)


При сравнении типобезопасности TS и JS, как оказалось, особой разницы выявить не удаётся. Сторонники TypeScript часто говорят о преимуществах типобезопасности, но нельзя сказать, чтобы типобезопасность значительно снижала плотность ошибок в продакшне. Это важный момент, так как применение ревью кода и TDD оказывает серьёзнейшее воздействие на устранение ошибок (одно лишь применение методики TDD приводит к снижению ошибок на 40–80%). Если совместить TDD с анализом архитектуры проектов, с проверкой спецификаций и с ревью кода, можно выйти на более чем 90% сокращение плотности ошибок. Многие из этих техник (в частности, TDD) способны помочь в нахождении тех же ошибок, которые можно обнаружить средствами TypeScript, а также многих ошибок, которые TypeScript обнаружить не в состоянии.

Здесь мы приведём некоторые выкладки из этого исследования. Теоретический максимум «общедоступных» ошибок, которые можно обнаружить средствами TypeScript — это около 15%. «Общедоступные» ошибки — это такие ошибки, которые пережили фазу разработки проекта и попали в общедоступный репозиторий.

В вышеупомянутом исследовании осуществлялось наблюдение за ошибками, о которых было известно заранее. Сюда входило и знание того, какие строки кода были изменены для исправления ошибок, в то время как проблема и её потенциальное решение были известны до типизации кода. Это означает, что даже знание о существовании ошибок не позволило, средствами TypeScript, обнаружить 85% «общедоступных» ошибок.

Почему же TypeScript не в состоянии обнаружить так много ошибок? Почему я говорю о том, что 15% обнаруженных ошибок — это теоретический максимум TypeScript? Для начала стоит отметить, что, в соответствии с рассматриваемым исследованием, ошибки в спецификациях приводят к возникновению примерно 78% ошибок в общедоступных GitHub-репозиториях. Невозможность чётко сформулировать спецификации программ или невозможность правильно реализовать спецификации ведут к самому распространённому типу ошибок. Это автоматически приводит к тому, что большую часть ошибок в программных проектах TypeScript не может выявить или предотвратить. Авторы исследования, кроме прочего, идентифицирую и классифицируют ошибки, не детектируемые средствами TypeScript. Вот гистограмма со сведениями о таких ошибках.

f794f6fe79822510073b098e9378b532.png


Ошибки, которые не детектируются средствами TypeScript

Пример «StringError» — это ошибка, которая возникает в том случае, если там, где нужна строка, используется строка, то есть ошибки в типах не возникает, но ошибку вызывает само содержимое этой строки (например — там может быть неправильный URL). Средствами статического анализа можно выявить некоторые из подобных ошибок, исследуя содержимое строк и используя описания этого содержимого. Но это даст лишь перспективу исправления небольшой доли от небольшого процента ошибок. В результате мы и говорим о том, что средствами TypeScript вряд ли когда-либо можно будет выявлять больше 15–18% ошибок.

Тут может показаться, что 15% — это уже довольно много. Почему TypeScript не может обнаружить значительно больший процент ошибок?

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

Предположим, что ваш проект содержал бы 1000 ошибок в том случае, если бы вы не применяли никаких мер по борьбе с ошибками. После того, как проект был как следует проверен, потенциальное количество ошибок, способных дойти до продакшна, сократилось до 100. Теперь, чтобы увидеть реальные возможности TypeScript, посмотрим на то, сколько из этих ошибок можно выявить с его помощью. Так как около 80% ошибок средствами TypeScript выявить нельзя, и учитывая то, что, в теории, все ошибки, выявляемые с помощью TypeScript, можно обнаружить и другими средствами, вроде использования методологии TDD, мы, поступив довольно щедро, предположим, что TypeScript выявит ещё 8% ошибок. Тут мы, кроме того, исходим из предположения, в соответствии с которым примерно половину ошибок, которые выявляет TypeScript, другими способами мы не обнаружили. В результате получается следующее:

  • Проект, в котором меры по борьбе с ошибками не применяются, содержит 1000 ошибок.
  • При использовании мер по борьбе с ошибками, не связанных с TypeScript, удалось выявить 900 ошибок.
  • После проверки проекта средствами TypeScript осталось 92 ошибки. Это значит, что благодаря внедрению TypeScript удалось обнаружить ещё 8 ошибок.


dbc4b6c915f29ef9ba9230813abe087c.png


Ошибки в проекте без проверок, ошибки, оставшиеся после выполнения ревью кода и после применения TDD, и ошибки, которые остались после проверки проекта средствами TypeScript

Кто-то может не согласиться с этими выводами, говоря, что при использовании статической системы типов не нужно писать огромное количество тестов. Но подобные аргументы не выдерживают никакой критики. TypeScript не заменяет другие средства борьбы с ошибками. Даже если в некоем проекте используется TypeScript, без других мер по поиску ошибок всё равно не обойтись.

ac0fbab03c7765b723318a3c4a5dc631.png


Ошибки, выявленные TypeScript и другими способами

Предположим, что средствами TypeScript было выявлено 15% от исходного количества ошибок вышеописанного гипотетического проекта. То есть — 150 из 1000. Но даже при таком подходе, если не учитывать ошибки, найденные TypeScript, другие средства поиска ошибок позволят найти 900 ошибок. Это ведёт к очевидности того факта, что, при выборе средств для борьбы с ошибками, речь не идёт о выборе TypeScript или чего-то ещё. Для поиска ошибок можно взять и TypeScript и другие средства, что, как показано выше, приведёт к обнаружению 908 ошибок из 1000 (напомним, что на эту цифру мы вышли, исходя из предположения о том, что другие средства поиска ошибок выявляют множество ошибок, которые можно обнаружить средствами TypeScript).

Мне приходилось реализовывать системы управления качеством в крупномасштабных проектах стоимостью многие миллионы долларов. Я могу сказать, что мои ожидания относительно эффективности подобных систем находятся в районе 30–80% уменьшения ошибок. Похожие цифры можно найти в следующих работах:

  • Проверки архитектуры проекта и спецификаций способны привести к устранению до 80% ошибок.
  • Применение TDD способно снизить число оставшихся ошибок на 40–80%.
  • Час, потраченный на ревью кода, экономит 33 часа поддержки проекта.


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

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

▍Новые возможности JavaScript и кросс-браузерная компиляция кода (New JS Features, Compile to Cross-Browser JS)


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

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

▍Поиск разработчиков (Recruiting)


Примерно половина из тех, кто участвовал в исследовании State of JavaScript, уже использовали TypeScript и планируют пользоваться им в будущем, при этом ещё 33.7% респондентов хотят изучить TypeScript. Но 5.4% пробовали TS и говорят о том, что снова им пользоваться не будут, а 13.7% заявляют о том, что не заинтересованы в изучении этого языка. Всё это уменьшает рынок предложения труда TS-разработчиков почти на 20%, что может оказать серьёзное влияние на проекты, которым нужны большие команды программистов. Поиск работников — дорогой процесс, который может занимать многие месяцы и мешать продуктивной работе уже нанятых программистов (которые, чаще всего, являются наиболее квалифицированными представителями компаний, способными оценить навыки кандидатов на рабочие места).

С другой стороны, если вам нужно нанять одного-двух разработчиков, то использование TypeScript может сделать ваше предложение более привлекательным для почти половины возможных соискателей. Маленький проект даже может от этого немного выиграть. Если же речь идёт о командах размером в сотни или тысячи разработчиков, то такая ситуация на рынке труда способна привести к негативному влиянию выбора TypeScript на такие проекты.

▍Подготовка к работе, начальное обучение (Setup, Initial Training)


Эти мероприятия выполняются лишь однажды, поэтому их стоимость сравнительно низка. Команды, уже знакомые с JavaScript, обычно выходят на высокую продуктивность TypeScript-разработки за 2–3 месяца, а за 6–8 месяцев выходят на очень высокий уровень владения языком. Это, конечно, дороже чем взять на работу готового специалиста, но, определённо, если бы все сложности, связанные с использованием TypeScript, этим бы и ограничивались, на это можно было бы пойти без особых раздумий.

▍Отсутствующие возможности (Missing Features)


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

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

▍Непрерывное обучение (Ongoing Mentorship)


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

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

Повышенное внимание к типизации постоянно отнимает время разработчиков. Нечто подобное можно наблюдать при приёме в команду нового программиста. Но это выражается и в том, что опытные TypeScript-разработчики, обнаружившие что-то полезное, делятся этим с командой. Это «непрерывное обучение» — всего лишь нормальный побочный эффект коллективной работы над проектом, и это здоровая привычка, которая позволяет экономить средства в долгосрочной перспективе. Но подобные вещи выливаются в затраты времени и сил, а значит — и в затраты в денежном выражении, а TypeScript лишь увеличивает подобные затраты.

▍Дополнительная нагрузка на программистов, связанная с типизацией (Typing Overhead)


В этот показатель я включаю ту дополнительную нагрузку на программистов, которую создаёт необходимость типизации сущностей, а также необходимость тестирования, отладки и поддержки аннотаций типов. Отладка типов — это та статья расходов на использование TypeScript, на которую нередко не обращают внимания. Аннотации типов подвержены собственным ошибкам. Типизация может быть слишком строгой, слишком свободной, или попросту неправильной.

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

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

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

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

«Синтаксический шум» представляет собой проблему по нескольким причинам. Код стремятся поддерживать в чистоте по тем же причинам, по которым стремятся поддерживать в чистоте жилища.

  • Если в коде много вспомогательных конструкций — там будет больше мест, в которых могут скрываться ошибки. Значит — в коде будет больше ошибок.
  • Большое количество вспомогательных конструкций означает, что в коде становится сложнее искать то, что нужно.


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

«Синтаксический шум» — одна из главных проблем TypeScript. Его можно уменьшить следующими способами:

  • Улучшение поддержки дженериков с использованием типов высших родов. Это позволит избавиться от некоторых «шумов» шаблонного кода (для того чтобы лучше это понять — взгляните на систему типов Haskell).
  • Поддержка использования, по умолчанию, отдельных, а не встроенных описаний типов. Если стандартом в области TypeScript-разработки станет стремление к тому, чтобы обходиться без встроенных описаний типов, тогда синтаксис типизации будет изолирован от реализации функций, что облегчит и восприятие сигнатур типов, и их реализаций, так как они не будут друг с другом смешиваться, соперничая за внимание программиста. Внедрить подобное можно, тщательно пересмотрев документацию, этому может поспособствовать и соответствующий настрой опытных TypeScript-разработчиков, отвечающих на вопросы на Stack Overflow.


Итоги


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

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

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

© Habrahabr.ru