- Em 2023, um PR de refatoração no repositório do Svelte chamou a atenção de céticos em relação ao TypeScript ao migrar o código para uma base com JSDoc
- O time do Svelte explicou que isso não era uma posição anti-TypeScript, mas parte de uma dependência contínua do TypeScript
- O texto enfatiza que JSDoc e TypeScript não devem ser vistos como opostos, e sim que o próprio JSDoc faz parte do TypeScript
- O TypeScript atua como motor de IntelliSense, sendo responsável tanto pela interpretação de comentários JSDoc quanto pelos recursos de autocompletar de código
- O JSDoc oferece a mesma capacidade de análise estática sem etapa de build e, em projetos JS modernos, na prática cumpre o mesmo papel do TypeScript
O PR do Svelte e o contexto da controvérsia
- Em maio de 2023, um PR de refatoração interna do repositório do Svelte chegou à primeira página do Hacker News
- O PR mudava declarações de tipo de arquivos
.ts para comentários JSDoc em arquivos .js
- Alguns interpretaram isso como uma rejeição às vantagens do TypeScript
- O criador do Svelte, Rich Harris, explicou diretamente no HN: “isso não é anti-TypeScript”
- Ele afirmou que o compromisso do Svelte com o TypeScript continua forte
- Depois desse episódio, surgiram muitos textos comparando “TypeScript vs JSDoc”, espalhando a visão do JSDoc como “TypeScript sem etapa de build”
A origem e a essência do TypeScript
- No fim dos anos 2000 e início dos anos 2010, o JavaScript era visto como uma linguagem com pouca autocompletação e segurança de tipos
- Desenvolvedores da Microsoft lidavam com isso usando o ScriptSharp para converter código C# em JS
- Foi nesse contexto que o TypeScript nasceu, essencialmente como uma ferramenta de build para melhorar o desenvolvimento em JS
TypeScript é IntelliSense
- O TypeScript não é apenas uma linguagem: ele atua como motor de IntelliSense
- Mesmo sem usar arquivos
.ts, recursos como autocompletar, informações de parâmetros e navegação por símbolos são fornecidos pelo serviço de linguagem do TypeScript
- Na maioria dos editores, mesmo ao escrever código JS, o serviço do TypeScript roda no backend
TypeScript é JSDoc
- O serviço de linguagem do TypeScript também é usado para interpretar comentários JSDoc
- O CHANGELOG do TypeScript frequentemente inclui recursos adicionados relacionados a JSDoc
- Projetos baseados em JSDoc também podem ser configurados com
tsconfig.json, e é possível executar checagem de tipos com o comando tsc
- Portanto, quem usa JSDoc na prática já está usando TypeScript
Experiência com projetos baseados em JSDoc
- O autor compartilha a experiência de ter reescrito o frontend de um projeto existente com anotações de tipo em JSDoc
- Tirando recursos de runtime como enum, a maior parte das expressões do TypeScript pode ser representada em JSDoc
- Generics têm uma sintaxe um pouco mais complexa, mas incentivam um uso mais ativo da inferência de tipos
- Em projetos com JSDoc, ao clicar numa função é possível ir para o código real, o que melhora a experiência de desenvolvimento
- O ecossistema de ferramentas do TypeScript também pode ser reaproveitado em projetos com JSDoc
- Ex.: bibliotecas que geram tipos a partir de esquemas OpenAPI ou GraphQL também conseguem gerar tipos em forma de comentários JSDoc
Conclusão e casos adicionais
- O JSDoc não é uma alternativa ao TypeScript, mas compartilha o mesmo sistema de análise estática
- Ele permite pular a etapa de build e ainda assim oferece segurança de tipos equivalente
- Além disso, o texto menciona o caso de migração do projeto webpack para JSDoc
- Como especialista em TypeScript, o autor deixa clara sua posição: “JSDoc é TypeScript”
1 comentários
Comentários no Hacker News
Resumo do que aprendi ao longo de vários anos desenvolvendo e mantendo software para web e robótica com Python/JavaScript
Tipos existem mesmo quando não são declarados, e, se você não os explicita, eles acabam existindo só na sua cabeça
Mas a cabeça é volátil e difícil de acessar por outras pessoas
Por isso, tipagem é uma excelente forma de documentação
JSDoc e TypeScript são formatos padrão para expressar tipos, e ambos têm prós e contras
O importante é definir tipos com consistência e previsibilidade
Um verificador de tipos é a forma que o computador tem de dizer: “então prove”
Nem todo programa precisa do mesmo nível de prova, e exigir prova demais pode ser desperdício
Por isso, eu prefiro linguagens que permitam “provar” apenas o necessário
Trabalhando, aprendi na prática que “outras pessoas” também inclui meu eu do futuro
Rust permite relaxar restrições com coisas como unsafe, Arc, clone, mas, em troca, faz você escolher explicitamente quais restrições não foram provadas
Já nas linguagens em que “não precisa provar”, é difícil saber qual abordagem foi adotada internamente
A abordagem do Rust pode ser usada de forma solta no começo, como Python, mas depois é muito mais vantajosa em legibilidade e escalabilidade
Eu não estava tentando defender uma ferramenta específica, só queria enfatizar que ambos são formas de expressar um sistema de tipos
Linguagens com tipagem estática eram muito mais fáceis de lidar em projetos em equipe, e até hoje prefiro tipos estáticos sempre que possível
Quando vejo definições de tipos TypeScript adicionadas depois a bibliotecas JS existentes, a complexidade é enorme
Um único tipo incorreto pode quebrar toda a compilação
No fim, linguagens dinâmicas precisam ser usadas na base do “se vira”
Eu gosto de tudo que pode ser feito em JavaScript sem etapa de build
A combinação de HTML/CSS moderno, Web Components e JSDoc é subestimada
Não serve para todo mundo, mas acho que é uma candidata totalmente viável a stack moderna de frontend
E, com recursos como HMR, o custo da etapa de build caiu bastante
Sempre passo por Vite ou Webpack, então não sinto na prática as vantagens de JS sem build
Queria que existisse uma forma mais fácil de construir componentes complexos
Rastrear requisições de rede, ir direto ao código-fonte, definir breakpoints — tudo fica muito mais intuitivo na depuração
Quanto maior a escala, mais esse ambiente ajuda
Na época em que SPA estava em alta, JSDoc foi a salvação para gerenciar tipos
Depois surgiu o Google Closure Compiler, oferecendo segurança de tipos baseada em JSDoc, e o TypeScript passou a suportar (TS)JSDoc junto com sua própria sintaxe
A comunidade acabou escolhendo TypeScript, e o Closure Compiler desapareceu
Por isso, (TS)JSDoc ficou como um resquício da época em que a MS competia com o Google
Hoje, TS oferece muito mais recursos, como genéricos, enums, utility types, testes de tipos com Vitest, type guards etc.
Eu uso TS e JSDoc juntos — TS para código, JSDoc para documentação (
@link,@see,@deprecated,@exampleetc.)Genéricos, utility types, type guards, parsing de regex e a maioria dos recursos de TS também podem ser usados no JSDoc
Em projetos pessoais, já implementei tudo só com JSDoc, inclusive genéricos
Dizer que (TS)JSDoc é um relicário do passado é desinformação, então isso não deveria ser espalhado sem verificação
Dizem que há muitos tipos que não podem ser expressos em JSDoc, mas acho que teria sido legal se ele tivesse permitido uma abordagem de linguagem completa, como Flow
TypeScript também poderia ter feito isso, e não sei por que não fez
Eu também pensava assim antes, mas mudei de ideia ao refatorar um projeto para JSDoc
Em JSDoc, também dá para definir slots genéricos com
@templateExemplo:
Link relacionado
Pacotes escritos com JSDoc oferecem uma boa experiência de desenvolvimento porque CMD/CTRL+clique leva ao código real
Há 5 anos, em um meetup, um palestrante disse que “se você não gosta de TypeScript, JSDoc é a alternativa”
Eu expliquei que, no fim das contas, os dois são TypeScript, mas meu chefe não acreditou em mim
JSDoc e TS expressam tipos de forma explícita, mas a sintaxe de TS é muito mais poderosa
Ainda assim, para quem quer manter o ambiente JS e aproveitar as ferramentas de tipos, JSDoc é uma ótima escolha
Em contraponto, JSDoc não é TypeScript
Tipos definidos com
@typedefsão exportados automaticamente, e não há como controlar issoIssue relacionada
Por causa disso, ao desenvolver bibliotecas, o IntelliSense ficava poluído e exposto demais, o que era incômodo
Você pode simplesmente copiar o arquivo “my-component.js” e ele funciona sem build
Mas, em projetos grandes, prefiro a sintaxe de TS
@importdá para resolver a maior parte dos casosConcordo com a afirmação de que “JSDoc não é uma alternativa ao TypeScript”
JSDoc também oferece análise estática, mas sem etapa de build
Veja a documentação oficial do Node
Mas TS baseado em JSDoc também funciona no navegador
Pessoalmente, prefiro a legibilidade da sintaxe de TS, e a remoção de tipos com ferramentas como
swcjá é rápida o bastanteO motivo de TypeScript ter vencido as outras alternativas foi que ele continuou sendo um verificador de tipos, não uma nova linguagem
No começo a direção oscilou um pouco, mas foi corrigida no momento certo, e hoje até enums raramente são usados na maior parte do código
No VSCode, se você ativar a opção “TypeScript: Prefer Go To Source Definition”, dá para ir ao código-fonte real
Além disso, se adicionar
declarationMap: truenotsconfig, funciona com ainda mais precisãoEu quase sempre prefiro ver o código-fonte no cmd+click