TypeScript 7.0 anunciado
(devblogs.microsoft.com)- O TypeScript 7.0 é uma versão que migra a toolchain para código nativo baseado em Go e, em builds completos de projetos grandes, normalmente oferece melhora de velocidade de 8 a 12 vezes
- O novo
tscé instalado pelo pacotetypescriptdo npm, como antes, e o suporte a editores funciona por meio de um servidor de linguagem baseado em LSP no VS Code, Visual Studio, WebStorm etc. - Em bases de código como
vscode,sentry,bluesky,playwrightetldraw, o tempo de build caiu bastante e, em alguns ambientes, o uso total de memória também diminuiu - O TypeScript 7.0 ainda não tem uma API de programação estável, então ferramentas que incorporam o TypeScript, como
typescript-eslint, Vue, MDX, Astro, Svelte e verificação de tipos de templates do Angular, precisam rodar em paralelo com o TypeScript 6.0 - Como há novos padrões e opções removidas, aplicar primeiro as mudanças do TypeScript 6.0 facilita a transição; uma nova API está prevista para o TypeScript 7.1
TypeScript nativo baseado em Go
- O TypeScript 7.0 é um port nativo da toolchain do TypeScript e usa uma nova base de código escrita em Go
- A migração foi feita preservando ao máximo a estrutura e a lógica da base de código existente, com foco em manter a consistência dos resultados e a compatibilidade entre os dois compiladores
- A nova base de código, por meio da velocidade de código nativo, multithreading baseado em memória compartilhada e várias otimizações, normalmente entrega resultados 8 a 12 vezes mais rápidos em builds completos
- A instalação pode ser feita por npm, como antes
npm install -D typescript
- Após a instalação, é possível usar o novo executável
tscno workspace, executando-o comnpx tsc
Redução do ciclo de feedback no desenvolvimento
- O TypeScript participa de várias etapas do processo de desenvolvimento, como carregamento do editor, localizar todas as referências, autocompletar, diagnósticos,
tsce modo--watch - O TypeScript 7 reduz o tempo de espera em todo esse processo, encurtando o ciclo de feedback
- Na base de código do VS Code, ao abrir um arquivo com erro, o tempo até o primeiro erro aparecer caiu de cerca de 17,5 segundos para menos de 1,3 segundo, ficando mais de 13 vezes mais rápido
- O suporte ao editor é baseado em LSP, e o novo servidor de linguagem usa multithreading para processar rapidamente solicitações simultâneas
- Usuários do VS Code podem instalar a extensão dedicada ao TypeScript 7, e o suporte ao TypeScript 7 também deve ser incluído no próprio VS Code nas próximas semanas
- A versão mais recente do Visual Studio ativa automaticamente o TypeScript 7 conforme o workspace
Desempenho de build e resultados de memória
- A comparação do tempo de build completo entre TypeScript 6 e 7 em grandes bases de código open source é a seguinte
| Base de código | TypeScript 6 | TypeScript 7 | Melhora de velocidade |
|---|---|---|---|
| vscode | 125,7 s | 10,6 s | 11,9 vezes |
| sentry | 139,8 s | 15,7 s | 8,9 vezes |
| bluesky | 24,3 s | 2,8 s | 8,7 vezes |
| playwright | 12,8 s | 1,47 s | 8,7 vezes |
| tldraw | 11,2 s | 1,46 s | 7,7 vezes |
- Nos mesmos builds, o TypeScript 7 também apresentou, em geral, uso total de memória menor
| Base de código | TypeScript 6 | TypeScript 7 | Variação de memória |
|---|---|---|---|
| vscode | 5,2 GB | 4,2 GB | -18% |
| sentry | 4,9 GB | 4,6 GB | -6% |
| bluesky | 1,8 GB | 1,3 GB | -26% |
| playwright | 1,0 GB | 0,9 GB | -11% |
| tldraw | 0,6 GB | 0,5 GB | -15% |
Validação em bases de código reais e feedback das equipes
- O projeto TypeScript executa dezenas de milhares de testes acumulados ao longo de mais de 10 anos em todos os commits da branch
main - Além desses testes, o TypeScript 7 foi validado em bases de código reais de grandes equipes internas e externas
- Dentro da Microsoft, as equipes de Loop, Office, PowerBI, Teams e Xbox validaram o TypeScript 7
- Externamente, Bloomberg, Canva, Figma, Google, Lattice, Linear, Miro, Notion, Sentry, Slack, Vanta, Vercel, VoidZero e outras testaram em suas bases de código e forneceram feedback
- O novo servidor de linguagem reduziu em mais de 80% os comandos de servidor de linguagem com falha e em mais de 60% os crashes do servidor em comparação com o TypeScript 6.0
- O feedback de equipes reais inclui os seguintes casos
- A Slack informou que, com o TypeScript 7, o tempo da merge queue caiu 40%, e o tempo de verificação de tipos no CI baixou de cerca de 7,5 minutos para 1,25 minuto
- A Vanta observou melhora de velocidade de build de até 9 vezes em um de seus grandes projetos
- A equipe Microsoft News Services economizou 400 horas por mês em tempo de espera de builds de CI
- A Canva informou que o tempo até o primeiro erro aparecer no editor caiu de cerca de 58 segundos para 4,8 segundos
Execução em paralelo com TypeScript 6.0
- O TypeScript 7.0 ainda não inclui API
- Uma API nova e diferente deve ser oferecida no TypeScript 7.1
- Até lá, para ferramentas que precisam de acesso programático ao compilador, é possível executar TypeScript 6.0 e 7.0 em paralelo
- O novo pacote de compatibilidade
@typescript/typescript6fornece o executáveltsc6e reexporta a API do TypeScript 6.0 - Para ferramentas como
typescript-eslint, que importam diretamentetypescriptcomo peer dependency, recomenda-se usar alias do npm
npm install -D typescript@npm:@typescript/typescript6
- Para usar a API do TypeScript 6 junto com o
tscdo TypeScript 7, é possível criar aliases como abaixo
{
"devDependencies": {
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2"
}
}
- O pacote existente
@typescript/native-previewvinha fornecendo builds nightly da nova base de código do TypeScript 7, com mais de 8,5 milhões de downloads semanais - Daqui em diante, os builds nightly serão retomados pela tag
nextdo pacote padrãotypescript
npm install -D typescript@next
Opções de controle de paralelização
-
O TypeScript 7.0 executa várias etapas, como parsing, verificação de tipos e emit, em paralelo
-
Parsing e emit são fáceis de executar de forma independente por arquivo, escalando em grandes bases de código com overhead relativamente baixo
-
As novas flags experimentais
--checkers,--builderse--singleThreadedajustam o comportamento de paralelização -
--checkers- O TypeScript 7.0 cria um número fixo de workers de verificação de tipos e divide sempre o trabalho da mesma forma para os mesmos arquivos de entrada, garantindo resultados idênticos
- O número padrão de workers de verificação de tipos é 4, e pode ser ajustado com
--checkers - Os resultados na mesma máquina usando
--checkers 8são os seguintes
Base de código TypeScript 6 TypeScript 7 --checkers 8Melhora de velocidade vscode 125,7 s 7,51 s 16,7 vezes sentry 139,8 s 12,08 s 11,6 vezes bluesky 24,3 s 2,01 s 12,1 vezes playwright 12,8 s 1,16 s 11 vezes tldraw 11,2 s 1,06 s 10,6 vezes -
Aumentar
--checkerspode acelerar o build ao aproveitar mais núcleos de CPU, mas normalmente vem acompanhado de maior uso de memória- Em runners de CI com poucos núcleos de CPU e pouca memória, reduzir o valor pode evitar overhead desnecessário
--checkers 1torna a verificação de tipos, na prática, single-threaded e elimina trabalho duplicado- Em casos raros, mudanças no número de
--checkerspodem revelar resultados dependentes da ordem; por isso, pode ajudar definir um número fixo de checkers em todo o ambiente de build
-
--builders--builderscontrola o número de builders de referências de projeto que podem ser executados simultaneamente ao rodar--build- Pode ser especialmente útil em monorepos com muitos projetos
- Aumentar o valor pode acelerar o build, mas também pode aumentar o uso de memória
- Há um efeito multiplicativo com
--checkers:--checkers 4 --builders 4pode executar até 16 verificadores de tipos ao mesmo tempo - Diferentemente de
--checkers, mudanças no número de--buildersnão devem produzir resultados diferentes - Builds com referências de projeto são, por padrão, limitados pelo grafo de dependências dos projetos
-
--singleThreaded--singleThreadedfaz o compilador inteiro rodar em uma única thread- Pode ser útil para depuração, comparação de desempenho entre TypeScript 6 e 7, orquestração externa de builds paralelos e ambientes com recursos muito limitados
- Essa flag não apenas limita a 1 o número de workers de verificação de tipos, como também faz parsing e emit serem executados em uma única thread
Novo modo --watch
- O TypeScript 7 refez completamente o modo
--watch - O novo
--watché baseado no file-watcher do bundler Parcel e oferece monitoramento de arquivos multiplataforma eficiente e estável - A biblioteca padrão de Go não tem uma API integrada de monitoramento de arquivos, e as bibliotecas de terceiros avaliadas apresentavam problemas de estabilidade, desempenho, suporte multiplataforma e integração com ferramentas de build
- Uma abordagem puramente baseada em polling funcionava em vários sistemas operacionais, mas tinha alto custo computacional em projetos grandes com muitas dependências em
node_modules - A equipe do TypeScript portou para Go o
@parcel/watcher, usado no VS Code, e usa um shim mínimo em assembly para evitar dependência de toolchains C++ - Esse watcher é um pacote independente e traz melhorias no uso de recursos em várias plataformas no modo
--watchdo TypeScript 7
Valores padrão do TypeScript 6.0 e mudanças de compatibilidade
- O TypeScript 7.0 foi feito para ser compatível com a verificação de tipos e o comportamento de linha de comando do TypeScript 6.0
- Código que compila sem problemas no TypeScript 6.0 com a flag
stableTypeOrderingativada e semignoreDeprecationsconfigurado deve compilar da mesma forma no TypeScript 7.0 - O TypeScript 7.0 adota os novos valores padrão do TypeScript 6.0 e gera hard error para flags e sintaxes depreciadas no TypeScript 6.0
- As principais mudanças de valores padrão de configuração são as seguintes
- O padrão de
strictétrue - O padrão de
moduleéesnext - O padrão de
targeté a versão ECMAScript estável atual imediatamente anterior aesnext - O padrão de
noUncheckedSideEffectImportsétrue - O padrão de
libReplacementéfalse - O padrão de
stableTypeOrderingétruee não pode ser desativado - O padrão de
rootDiré./ - O padrão de
typesé[], e o comportamento anterior pode ser restaurado com["*"]
- O padrão de
- As mudanças em
rootDiretypessão apontadas como as que podem causar mais surpresa- Projetos em que o
tsconfig.jsonfica fora de um diretório de código-fonte comosrcprecisam declararrootDirexplicitamente para manter a estrutura de diretórios existente - Projetos que dependem de declarações globais específicas precisam declarar os pacotes
@typesnecessários emtypes
- Projetos em que o
{
"compilerOptions": {
"rootDir": "./src"
},
"include": ["./src"]
}
{
"compilerOptions": {
"types": ["node", "jest"]
}
}
Comportamentos removidos ou que viraram hard error
- No TypeScript 7.0, várias opções e sintaxes depreciadas no TypeScript 6.0 deixam de ser compatíveis
- Os principais itens são os seguintes
- Sem suporte a
target: es5 - Sem suporte a
downlevelIteration - Sem suporte a
moduleResolution: node/node10; recomenda-senodenextebundler - Sem suporte a
module: amd, umd, systemjs, none; recomenda-seesnextoupreservejunto com resolução de módulos baseada em bundler ou navegador - Sem suporte a
baseUrl;pathspode ser atualizado para caminhos relativos a partir da raiz do projeto em vez debaseUrl - Sem suporte a
moduleResolution: classic; recomenda-sebundlerounodenext esModuleInteropeallowSyntheticDefaultImportsnão podem ser definidos comofalsealwaysStricté tratado comotruee não pode ser definido comofalse- Não é permitido usar a palavra-chave
moduleem declarações de namespace - Não é permitido usar a palavra-chave
assertsem imports; é preciso usarwithpara acompanhar a mudança na sintaxe de import attributes do ECMAScript - Sob
skipDefaultLibCheck, diretivas/// <reference no-default-lib />deixam de ser respeitadas - Se houver um
tsconfig.jsonno diretório atual, builds pela linha de comando não podem receber caminhos de arquivos, sendo necessário usar--ignoreConfigexplicitamente
- Sem suporte a
Mudanças em tipos de template literal e suporte a JavaScript
- O TypeScript 7.0 trata code points Unicode de forma mais natural na inferência de tipos de template literal
type HeadTail<S> = S extends `${infer Head}${infer Tail}` ? [Head, Tail] : never;
type Result = HeadTail<"😀abc">;
// 7.0: ["😀", "abc"]
// anterior: ["\ud83d", "\ude00abc"]
- Antes, seguindo o comportamento de indexação UTF-16 do JavaScript,
"😀"era dividido nas duas partes de um surrogate pair - O novo comportamento combina com a intuição de tratar
"😀"como uma única unidade, como emfor...ofou[...str] - Pode ser uma breaking change para manipulação de strings em nível de tipo que modelava intencionalmente code units UTF-16
- O suporte a JavaScript foi reformulado para ficar mais consistente com a forma como arquivos TypeScript são analisados
- Não é possível usar valores em posições de tipo; é preciso usar
typeof someValue @enumdeixa de receber tratamento especial?isolado não pode ser usado como tipo; é preciso usarany@classnão transforma uma função em construtor; é preciso usar uma declaraçãoclass- O postfix
!não é compatível - Nomes de tipos devem ser definidos dentro de tags
@typedef - A sintaxe de funções no estilo Closure deixa de ser compatível; é preciso usar a sintaxe abreviada do TypeScript
- Não é possível usar valores em posições de tipo; é preciso usar
- Alguns padrões JavaScript, como aliasing de
thise reatribuição completa deprototypede funções, também deixam de receber tratamento especial - As diferenças entre TypeScript 6.0 e 7.0 estão sendo detalhadas em
CHANGES.md
Recursos e limitações do editor
- O TypeScript 7.0 adiciona vários recursos de editor que estavam ausentes desde o beta
- Inclui importação automática, hovers extensíveis, inlay hints, code lens, go-to-source-definition, edição vinculada de JSX, conclusão de tags, entre outros
- Também traz recursos que ficaram de fora do beta do TypeScript 7.0, como semantic highlighting, “sort imports” e “remove unused imports”
- Para melhorar a qualidade do servidor de linguagem, a infraestrutura de testes e diagnósticos foi reconstruída, e é possível executar fuzz tests em grandes bases de código TypeScript e JavaScript do GitHub
Restrições atuais dos fluxos de trabalho com linguagem incorporada
- Fluxos de trabalho que usam Vue, MDX, Astro, Svelte etc. provavelmente ainda não conseguirão aproveitar o TypeScript 7
- Verificações de tipos em templates especiais, como templates do Angular, também provavelmente não conseguirão usar o TypeScript 7
- O principal motivo é que o TypeScript 7 ainda não expõe uma API de programação estável
- Ferramentas que incorporam o TypeScript em seu próprio compilador e serviço de linguagem, como o Volar, no momento não têm alternativa a não ser depender do TypeScript 6.0
- A equipe do TypeScript vê esse problema como uma limitação pontual e planeja trabalhar com os mantenedores desses projetos para garantir suporte ao TypeScript 7
- Até lá, recomenda-se usar o TypeScript 7 em cenários que não exigem language server plugins
- Projetos Angular podem usar o
tscdo TypeScript 7 no CLI para detectar rapidamente erros no projeto inteiro, enquanto usam também o TypeScript 6.0 para suporte no editor - Vue, MDX, Astro, Svelte e similares devem continuar usando o TypeScript 6.0 por enquanto
- No VS Code, é possível voltar para o TypeScript 6.0 com o comando “Disable TypeScript 7 Language Server”
Planos futuros
- O lançamento do TypeScript 7.0 é um marco importante do port nativo no qual o projeto TypeScript se concentrou por mais de um ano
- Após o 7.0, o foco voltará ao trabalho em novos recursos, melhorias de usabilidade, melhorias adicionais de desempenho e implementação de novas APIs para o ecossistema
- Espera-se que novos lançamentos com recursos saiam a cada 3 a 4 meses, de forma semelhante ao período anterior ao TypeScript 7.0
- O TypeScript 7.1 deve trazer o fechamento de lacunas para ajudar a transição da comunidade e a oferta de novas APIs
2 comentários
Comentários do Hacker News
De acordo com os próprios testes deles, os ganhos de velocidade do TypeScript 7 são os seguintes
É impressionante que a equipe tenha alcançado esse resultado fazendo a migração com responsabilidade. Queria que o Bun aprendesse com isso. Minha dúvida é qual é o impacto nas ferramentas auxiliares que precisam compilar a base de código TypeScript, como tsdown ou esbuild, e se já dá para usar TS 7 com o tsdown atual
--isolatedDeclarations; caso contrário, basta instalar o TypeScript 6 em paralelo, como orientado no blogHouve uma época em que se discutia se os tipos valiam o esforço que exigiam. O grande mérito do TypeScript, acima de tudo, foi popularizar os tipos
Por exemplo, já ouvi várias vezes gente dizendo que Python não servia por não ter tipos, o que não faz sentido. Python é uma linguagem fortemente tipada e, ao mesmo tempo, dinamicamente tipada.
Existem linguagens realmente sem tipos ou geralmente “stringly typed”. O AREXX, com o qual mexi quando era criança, tratava todos os valores como strings, mesmo quando pareciam números, e a maioria das ferramentas Unix CLI como o sed também pode ser vista assim. Mas a maior parte das discussões sobre tipos girava em torno de linguagens dinamicamente tipadas como Python, e quase nunca vi alguém dizer que linguagens fracamente tipadas ou sem tipos são boas para projetos grandes. Pelo contrário, ouvi muito chamarem Python erroneamente de linguagem “sem tipos” para dizer que não servia para projetos grandes, e isso sempre foi confuso para mim, já que eu de fato construía projetos grandes em Python
Minha exposição anterior a tipos era basicamente C++/Java, e especialmente C++ dificilmente serve como bom exemplo de qualquer coisa além de como criar uma linguagem excessivamente complexa. Depois que você vê tipos bem aplicados, fica muito mais fácil convencer alguém
O que realmente impressiona aqui é uma equipe excelente mantendo simultaneamente duas bases de código separadas para o sistema de tipos mais avançado conhecido pela humanidade. Também estou ansioso pela reescrita em Rust
O tempo de desenvolvimento em Rust seria muito maior. Rust pode ser 20% mais rápido que Go, mas o ganho obtido ao sair de TypeScript para Go já é enorme. Talvez no vscode desse 14x em Rust em vez de 11x com Go, mas só o Go já é mais do que suficiente para causar um grande impacto
Não estou tentando diminuir o sistema de tipos do TypeScript; na verdade, é um trabalho muito interessante
Depois de alguns anos usando TypeScript, agora acho realmente incômodo ter que adicionar anotações de tipo manualmente em Python e recorrer a recursos básicos da linguagem como
abcInteressante, mas hoje em dia quase não executo mais o TSC, porque o Node agora remove anotações de tipo TypeScript nativamente. Só rodo quando preciso criar uma grande mudança regressiva e verificar, pela saída estática do compilador, o que não consegui atualizar
Até o código frontend que vai para o navegador depende dessa remoção de tipos do Node
Fico feliz que a sintaxe de tipos do JSDoc continue recebendo atenção. É minha forma preferida de usar TypeScript em projetos pessoais. Algumas mudanças de sintaxe vão ser chatas de atualizar, mas no geral quase tudo parece ser uma melhoria
[1] https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...
A grande dor do TypeScript é que é difícil ajustar o escopo das configurações do
tsconfigcomolibetypespara partes do projetoO projeto é um app web, mas por causa de
vite.config.ts, Playwright e testes unitários, os tipos de Node acabam entrando no lado das ferramentas da IDE. Mesmo que você adicione APIs de Node a um componente React, otscnão reclama.Atualmente, para isolar as bibliotecas DOM e Node, é preciso uma salada de referências de projeto, vários
tsconfig.jsone arquivos de saídatsbuildinfo, e também é trabalhoso usar referências de projeto evitando a geração de tiposMesmo em uma aplicação única, prefiro nx e movo o código compartilhado para “bibliotecas”. Uso bibliotecas que não são compiladas, e isso funciona muito bem em projetos grandes
A API do compilador TypeScript ainda não existe, mas como disseram que está em andamento, isso anima
Vendo o gráfico em que o uso de memória cai e o desempenho sobe bastante, dá a impressão de que talvez no servidor devesse ser usado Go em vez de TypeScript
E eu realmente não entendo por que alguém hoje começaria um projeto novo em TS/JS/Python tendo outras opções
Parabéns à equipe do TypeScript. Eu teria muito a dizer em texto longo ou em áudio, mas resumindo: o ecossistema JavaScript/TypeScript é parecido com trabalhar com madeira
Dá para fazer coisas de madeira laminada barata, tipo papelão, ou móveis estilo Ikea. Em termos de código, seriam apps de vibe coding sem originalidade.
Por outro lado, também dá para fazer móveis artesanais de alto nível ou até edifícios altos de madeira. Como usar madeira jovem para fazer vigas resistentes ao fogo com junções sob medida e técnicas de laminação. No ecossistema JavaScript/TypeScript também é possível criar resultados sofisticados, usando IA como uma poderosa máquina-ferramenta, mas com espírito artesanal. Se você tem coragem de construir algo e colocar para rodar, pode abraçar o ecossistema TypeScript/JavaScript.
Opiniões no Lobste.rs
Entendo o motivo, mas é interessante a mudança de um compilador auto-hospedado para um compilador que não é auto-hospedado
É um movimento raro de se ver, porque normalmente quase sempre se vai na direção oposta
A auto-hospedagem exerce uma pressão forte para que a linguagem evolua para uma linguagem melhor para escrever compiladores, e isso nem sempre pode ser a direção correta
Mesmo que eu não programe em TypeScript, o próprio VSCode é escrito em TypeScript, então fico curioso se essa melhoria também afeta a velocidade do VSCode
Ou se afeta apenas a extensão de linguagem TypeScript
O que fica mais rápido aqui é apenas o compilador que recebe código TypeScript e o transforma em JavaScript, e esse processo acontece no pipeline de build antes de a Microsoft distribuir o executável do VSCode
Uma possível exceção é que o servidor LSP do TypeScript também pode ficar mais rápido, porque ele de fato faz parsing de código TypeScript durante a execução. Mas isso é independente do fato de o VSCode ser escrito em TypeScript
tscnão deve mexer no código que está processando, exceto pelo mínimo, como remover tiposPor isso, espero que as características de desempenho das ferramentas feitas com TypeScript praticamente não mudem
Uma pequena dica que obtive pessoalmente. O projeto em que trabalho atualmente usa TS 5, mas, como esperado, eu não queria usar isso no nvim
Então primeiro instalei o TS 7 com mise e criei, dentro de
node_modules/.bin, um link simbólicotsgoapontando para o TS instalado pelo miseComo o nvim-lspconfig ainda usa o antigo nome de arquivo
tsgoda época do preview técnico, o nvim acaba executando o TS 7 instalado em vez do TS local