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

Контекст

Недавно наметилась такая тенденция: язык JavaScript требует сократить время, затрачиваемое на итерацию разработки, то есть, сократить количество этапов сборки. Иными словами, «чтобы стало быстрее и проще».

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

Возвращаясь в 2012 год, когда был впервые анонсирован TypeScript, убедимся, что тогда мир JavaScript резко отличался от нынешнего. Некоторые браузеры (но не все) обновлялись часто. Было непонятно, как долго нам еще жить с допотопными версиями Internet Explorer, и именно поэтому такую популярность набирали сборщики и компиляторы. TypeScript должен был просто цвести в эпоху, когда добавление лишнего шага сборки в JavaScript воспринималось как данность – в конце концов, если вам все равно придется компилировать JavaScript, то почему бы на этом этапе не решить и вопрос с типами? Но, если вышеупомянутые тенденции продолжатся, то компиляция типов может стать единственным промежуточным этапом между написанием TypeScript и его выполнением, а мы не хотим остаться крайними, теми, кто мешает хорошему разработчику с удобством решать поставленные задачи!

В некоторых отношениях обеспечиваемая нами поддержка JavaScript ликвидирует этот разрыв – в чем вы могли убедиться, если вы работали в таком редакторе как Visual Studio или Visual Studio Code. Сегодня можно прямо в редакторе создать файл .js и начинать впрыскивать в него типы в виде комментариев JSDoc.

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

Поскольку это всего лишь комментарии, они вообще не влияют на выполнение вашего кода, а просто документируют его. Но в TypeScript они применяются для того, чтобы вам было удобнее редактировать JavaScript благодаря таким возможностям, как автозавершение кода, рефакторинг и пр. Можно даже добавить проверку типов, поставив в начале файла комментарий // @ts-check или прогнав эти файлы через компилятор TypeScript при помощи checkJs. Такая фича чрезвычайно упрощает некоторые варианты работы с TypeScript без шага сборки, и ее можно использовать с небольшими скриптами, простейшими веб-страницами, серверным кодом в Node.js, т.д.

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

А что, если бы у нас было обе эти возможности?

Что, если бы у нас было что-то вроде синтаксиса TypeScript, но на уровне JavaScript эта информация бы полностью игнорировалась, точно как комментарии?

function add(a: number, b: number) {
    return a + b;
}

Мы считаем, что потенциально здесь очень много возможностей, и в марте 2022 года планировалось оформить эту идею в виде предложения и подать в TC39, комитет стандартизации ECMAScript!

Как это должно работать?

Когда нас спрашивают, "когда ожидать появления типов в JavaScript?", мы затрудняемся с ответом. Исторически проблема заключается в том, что, если спросить разработчиков, что они понимают под типами в JavaScript, ответы будут самыми разными. Кто-то полагает, что типы должны полностью игнорироваться, а другие считают, что какое-то значение у типов должно быть – возможно, обязывать проведение какой-либо валидации во время выполнения, либо подвергаться интроспекции, либо что должны действовать в качестве подсказок движку и упрощать оптимизацию, и пр. Но в последние годы мнения сходятся в том, что лучше всего при проектировании придерживаться той линии, которой следовал TypeScript: во время выполнения типы полностью игнорируются как синтаксис и поддаются стиранию. Такой консенсус, вместе с широким применением TypeScript, помог нам увереннее себя чувствовать, обсуждая со специалистами по JavaScript и TypeScript предложение, сводящееся к «реализации типов в виде комментариев».

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

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

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

Чтобы все это состоялось, в языке JavaScript нужно, как минимум, добавить синтаксис для таких вещей как аннотирование типов у переменных и функций, модификаторы опциональности (?) для параметров и членов классов, объявления типов (псевдонимы для interface и type) и операторы утверждения типов (as и !) – все это не повлияло бы на выполнение окружающего кода.

Такие вещи как модификаторы видимости (напр. publicprivate и protected) также могут войти в число обсуждаемых тем; правда, перечисления, пространства имен и свойства параметров в рамках данного предложения рассматриваться не будут, поскольку во время выполнения проявляют наблюдаемое поведение. Эти возможности можно предложить в качестве отдельных фич ECMAScript, в зависимости от того, как отреагирует аудитория, но исходная цель такова: поддерживать некоторое большое подмножество TypeScript, которое, на наш взгляд, стало бы ценным дополнением к JavaScript.

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

О чем речь не идет?

Стоит отметить, о чем в этом предложении речь не идет.

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

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

Заключение

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

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

 

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


  1. tlekhatkova
    21.04.2022 15:05

     Спасибо за перевод. Только редакторской правки не хватает: все эти "такой как", "то что" вполне можно опустить.



    1. SergeiMinaev
      21.04.2022 16:25
      +2

      Краткий пересказ: давайте сделаем в JS аннотации типов, как в Python.


  1. CoolCmd
    21.04.2022 16:26

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


  1. NeoCode
    21.04.2022 23:25
    +1

    Говорят, что TypeScript спроектирован таким образом, что JavaScript - просто подмножество TypeScript. А если так, то почему не перенести все фичи TypeScript оптом в JavaScipt и не сделать единый язык?


    1. iliazeus
      22.04.2022 12:14
      +1

      Например, потому, что TypeScript все еще активно развивается, и ломающие изменения есть почти в каждой новой версии. JavaScript, напротив, развивается очень консервативно, по принципу "don't break the Web".


  1. qbz
    22.04.2022 15:30

    Я люблю тайпскрипт, но этот пропоузал какой-то бред, кмк. Вводить "типы как комментарии" только чтобы не компилить TS - какой-то абсурд. Либо вводить типы как типы, либо ничего не менять. Завтра фейсбук скажет - давайте синтаксис JSX введем нативно, нам так хочется.


  1. IAMBIRD
    22.04.2022 20:13

    Вижу два ключевых момента, к которым стоило бы придти:

    1. Внедрение нативного TS (или его подобия) наравне с JS, просто script lang другой, чтобы не мешалось.

    2. Переход WASM на AOT вместо JIT.

      В теории при решенном втором пункте первый уже не будет так актуален.

      Более того можно вообще весь JS в браузере транслировать в WASM и так гонять.


    1. demimurych
      23.04.2022 08:32

      в wasm не может быть aot компиляции бай дизайн.

      компилировать js в wasm это практически масло маслянное.


  1. demimurych
    23.04.2022 08:40

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

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

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