Добавить `defer` из Go в компилятор TypeScript: педагогический патч в компиляторе, написанном на Go

Разработка & Кодинг yesterdayВ закладки

Добавить `defer` из Go в компилятор TypeScript: педагогический патч в компиляторе, написанном на Go
Иллюстрация : Momiji Shirogane

Эндрю Хили внедряет ключевое слово `defer` — основной элемент кода Go — непосредственно в компилятор TypeScript, который теперь написан на Go. Это наглядный пример для понимания парсера, чеккера и эмиттера.

Точка отсчёта

С тех пор как Microsoft объявила о переписывании компилятора TypeScript на Go (проект «TypeScript Native», который обещает ~10-кратное ускорение по сравнению с историческим tsc на TypeScript), исходный код компилятора стал отличной площадкой для экспериментов. Эндрю Хили публикует на своём блоге очень поучительную статью, где добавляет в своём форке ключевое слово defer — один из столпов эргономики языка Go — в TypeScript.

Напоминание для тех, кто пришёл в основном из JS-стэка: в Go defer планирует выполнение функции на момент возврата из объемлющей функции. Это эквивалент try { … } finally { … } без boilerplate, с вызовом очистки, написанным рядом с тем вызовом, который его сделал необходимым:

f, _ := os.Open("file.txt")
defer f.Close() // выполнится при выходе из функции
// … остальной код

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

Что здесь разбирается

Интерес статьи не в том, что «defer от Go скоро появится в TypeScript» (спойлер: нет). Речь о том, чтобы пошагово проследить, что делает современный компилятор, когда добавляется новое ключевое слово. Хили проходит через:

  1. Сканер (лексер) — распознавание defer как отдельного токена, а не обычного идентификатора.
  2. Парсер — определение, где defer может появляться в грамматике (на уровне statement — да; в выражениях — нет).
  3. Чекер (type-checker) — проверка, что откладывается именно вызов функции.
  4. Эмиттер — трансляция defer в JavaScript, что в его случае сводится к обёртыванию объемлющей функции в try/finally и добавлению отложенных колбэков в массив, который выполняется при unwind.

Именно последний этап даёт больше всего знаний: defer в Go — это настоящий механизм языка (реализованный рантаймом), тогда как в JS ничего подобного нет — его приходится имитировать через desugaring, со всеми вытекающими компромиссами (производительность, исключения, await и т. д.).

Почему это интересно лично нам

Поскольку компилятор TypeScript на Go открыт, такие упражнения — идеальное чтиво, чтобы:

  • Понять архитектуру настоящего современного компилятора (не университетской игрушки).
  • Увидеть, как целевой язык (JS) ограничивает выбор трансляции, когда в нём нет нужной примитивы.
  • Ознакомиться с этапами AST → typechecking → emission на проекте, поверхность которого уже знакома (tsc).

Отметим, что патч Хили предлагается в качестве демо, а не как PR в основной репозиторий — TC39 никогда не включал defer в стандарт JavaScript, а Microsoft не продвигает проприетарные расширения такого рода в TypeScript.

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

Resources

Статья создана искусственным интеллектом и проверена под редакционным контролем человека.

Наша редакция
Была ли статья полезной?

7 чел. оценили эту статью

Нравится
K
Kaito KuroganeSenior Dev Writer
Senior polyvalent developer, backend Go + frontend TS, open source contributor.
Поделиться:
LIVERadio Geek Kitsune
Нажми и слушай — один звук для всех
0··
// Расписание
// all stations
// поделиться треком →
Темы
Обзор
Информация