Adicionar o `defer` de Go ao compilador TypeScript: um patch pedagógico em um compilador escrito em Go

Dev & Code yesterdayAdicionar aos favoritos

Adicionar o `defer` de Go ao compilador TypeScript: um patch pedagógico em um compilador escrito em Go
Ilustração : Momiji Shirogane

Andrew Healey injeta a palavra-chave `defer` — pilar do código Go — diretamente no compilador TypeScript, agora escrito em Go. Um caso de estudo para entender parser, checker e emitter.

O ponto de partida

Desde que a Microsoft anunciou a reescrita do compilador TypeScript em Go (o projeto "TypeScript Native", que visa ~10× de velocidade em comparação com o histórico tsc em TypeScript), o código-fonte do compilador tornou-se um terreno de jogo muito interessante. Andrew Healey publicou em seu blog um artigo muito didático onde adiciona, em seu fork, a palavra-chave defer — um dos pilares ergonômicos da linguagem Go — ao TypeScript.

Lembrete para quem vem principalmente da stack JS: em Go, defer agenda uma função para ser executada no momento em que a função envolvente retorna. É o equivalente a um try { … } finally { … } sem a verbosidade, com a chamada de limpeza escrita logo ao lado da chamada que a tornou necessária:

f, _ := os.Open("file.txt")
defer f.Close() // será executado ao sair da função
// … restante do código

O padrão é amplamente utilizado para liberar recursos (arquivos, mutexes, conexões) sem se perder em aninhamentos.

O que isso analisa em detalhes

O interesse do artigo não é "o defer do Go estará no TypeScript amanhã" (spoiler: não). Trata-se de acompanhar, passo a passo, o que um compilador moderno faz ao adicionar uma palavra-chave. Healey passa por:

  1. O scanner (lexer) — reconhecer defer como um token dedicado em vez de um identificador comum.
  2. O parser — decidir onde defer tem permissão para aparecer na gramática (ao nível de statement, sim; em expressão, não).
  3. O checker (type-checker) — verificar que o que está sendo adiado é realmente uma chamada de função.
  4. O emitter — traduzir defer para JavaScript, o que, no caso dele, equivale a envolver a função envolvente em um try/finally e empilhar os callbacks adiados em um array executado no desempilhamento.

Esta última etapa é a que mais ensina: defer no Go é um verdadeiro mecanismo da linguagem (implementado pelo runtime), enquanto em JS não temos nada comparável — é preciso simulá-lo por meio de um desugaring, com os compromissos que isso implica (desempenho, exceções, await, etc.).

Por que isso é interessante para nós

Como o compilador TypeScript em Go é open source, esse tipo de exercício é exatamente o que devemos ler para:

  • Entender a arquitetura de um verdadeiro compilador moderno (não um brinquedo acadêmico).
  • Ver como uma linguagem alvo (JS) restringe as escolhas de tradução quando não possui a primitiva necessária.
  • Familiarizar-se com a passagem AST → typechecking → emissão, em um projeto cuja superfície já conhecemos (tsc).

Observamos, ainda, que o patch de Healey é proposto como demonstração, não como PR upstream — o TC39 nunca adotou defer para o JavaScript padrão, e a Microsoft não está empurrando uma extensão proprietária desse tipo no TypeScript.

Para guardar: o verdadeiro ganho da reescrita em Go do tsc não é apenas a velocidade — é também um compilador cujo código finalmente é acessível para um leitor que não é especialista em TypeScript avançado. Esse tipo de patch pedagógico vai se multiplicar, e é uma excelente escola.

Resources

Artigo produzido por inteligência artificial, revisto sob controlo editorial humano.

A nossa redação
Este artigo foi-lhe útil?

7 pessoas gostaram deste artigo

Gosto
K
Kaito KuroganeSenior Dev Writer
Senior polyvalent developer, backend Go + frontend TS, open source contributor.
Partilhar:
LIVERadio Geek Kitsune
Toca para ouvir, o mesmo som para todos
0··
// Programa
// all stations
// partilhar uma faixa →
Secções
Explorar
Informações