Anunciado o TypeScript 6.0
(devblogs.microsoft.com)- A última release da atual base de código em JavaScript e uma release de transição para preparar a migração ao TypeScript 7.0, o port nativo escrito em Go
- Inclui melhorias na inferência de tipos e na resolução de módulos, como redução da sensibilidade ao contexto para funções que não usam
thise suporte a subpath imports começando com#/ - Grande modernização dos valores padrão das opções do compilador, como
strictcom padrãotrue,targetcom padrãoes2025etypescom padrão[] - Descontinuação em massa de opções legadas, como target ES5, módulos AMD/UMD/SystemJS,
--baseUrle--moduleResolution node10 - Adicionado suporte de tipos para propostas Stage 4 mais recentes do ECMAScript, como a API Temporal,
getOrInsert/getOrInsertComputeddeMapeRegExp.escape
O posicionamento do TypeScript 6.0
- É a última release baseada na atual base de código em JavaScript e serve como ponte para a transição ao TypeScript 7.0 (port nativo em Go)
- O TypeScript 7.0 aproveita código nativo e multithreading com memória compartilhada e já está muito próximo de ficar pronto
- A maior parte das mudanças do 6.0 existe para alinhar e preparar a adoção do 7.0
- Já é possível testar o TypeScript 7.0 antecipadamente pela extensão do VS Code ou pelo pacote npm
Mudanças desde o Beta e o RC
- Ajuste na checagem de tipos de expressões de função em chamadas genéricas, especialmente expressões JSX genéricas — isso detecta mais bugs no código existente, mas alguns usos podem passar a exigir argumentos de tipo explícitos
- Aplicada também às chamadas
import()a descontinuação estendida da sintaxe de import assertion (assert) - Atualização dos tipos DOM — refletindo os padrões web mais recentes, incluindo ajustes relacionados à API Temporal
Redução da sensibilidade ao contexto em funções que não usam this
- Durante a inferência de tipos, o TypeScript classifica como funções sensíveis ao contexto (contextually sensitive function) as funções com parâmetros sem tipo explícito e as processa mais tarde na ordem de inferência
- Funções escritas com sintaxe de método têm um parâmetro implícito
this, então, ao contrário de funções arrow, sempre eram tratadas como sensíveis ao contexto- Isso podia fazer a inferência falhar dependendo da ordem dos métodos dentro de um objeto literal
- No TypeScript 6.0, funções em que
thisnão é realmente usado deixam de ser consideradas sensíveis ao contexto- Essas funções passam a ter prioridade mais alta na inferência, permitindo inferência correta independentemente da ordem dos métodos
- Implementado com contribuição de Mateusz Burzyński neste PR
Suporte a Subpath Imports começando com #/
- O recurso de subpath imports do Node.js permite definir aliases para módulos internos do pacote pelo campo
importsnopackage.json - Antes, era obrigatório haver um caractere após
#, então não era possível usar caminhos começando com#/- Isso causava confusão para desenvolvedores acostumados à convenção de prefixo
@/em bundlers
- Isso causava confusão para desenvolvedores acostumados à convenção de prefixo
- O Node.js recentemente passou a suportar subpath imports iniciando com
#/- Agora é possível usar mapeamentos mais concisos como
"#/*": "./dist/*"
- Agora é possível usar mapeamentos mais concisos como
- O TypeScript 6.0 oferece suporte a isso com
--moduleResolution nodenextebundler - Implementado com contribuição de magic-akari neste PR
Combinação permitida de --moduleResolution bundler com --module commonjs
- Antes,
--moduleResolution bundlersó podia ser usado com--module esnextou--module preserve - Com a descontinuação de
--moduleResolution node(node10), essa nova combinação passa a ser o caminho de upgrade mais adequado para muitos projetos - No longo prazo, a recomendação é migrar para
--module preserve+--moduleResolution bundlerou--module nodenext
Flag --stableTypeOrdering
- Os IDs de tipo atribuídos internamente pelo TypeScript dependem da ordem de processamento, e os tipos union são ordenados com base neles
- Isso pode gerar comportamentos imprevisíveis, em que o resultado do emit de declarações muda conforme a ordem das declarações
- O TypeScript 7.0 introduz checagem de tipos paralela, então, para resolver o problema de IDs não determinísticos, usa um algoritmo de ordenação determinística baseado no conteúdo
- Ex.:
100 | 500será sempre emitido na mesma ordem
- Ex.:
- Ao ativar
--stableTypeOrderingno 6.0, é possível alinhar o comportamento de ordenação de tipos ao do 7.0, reduzindo diferenças entre as duas bases de código- Pode haver queda de desempenho de até 25% na checagem de tipos
- Se surgirem erros de tipo por diferenças de inferência, eles podem ser resolvidos com argumentos de tipo explícitos ou anotações de variáveis
- É uma flag pensada apenas para diagnosticar migrações do 6.0 para o 7.0; não é recomendada para uso prolongado
Opção es2025 (target e lib)
- O ES2025 não traz novos recursos de linguagem JavaScript, mas adiciona tipos para APIs built-in como
RegExp.escape - Itens que estavam em
esnext, comoPromise.try, métodos deIteratore métodos deSet, foram movidos paraes2025 - Implementado com contribuição de Kenta Moriuchi neste PR
Suporte de tipos para a API Temporal
- Os tipos built-in da proposta Temporal, que chegou ao Stage 4, foram incluídos no TypeScript 6.0
- Pode ser usado com
--target esnextou"lib": ["esnext"](ou o item granularesnext.temporal) - APIs como
Temporal.Now.instant().subtract()e.add()podem ser usadas com segurança de tipos - Já está disponível em vários runtimes e, com o Stage 4, passou a ser parte oficial da linguagem JavaScript
- Implementado com contribuição de Renegade334 neste PR
Suporte de tipos para os métodos de "upsert" de Map (getOrInsert / getOrInsertComputed)
- Simplifica o padrão repetitivo de verificar se uma chave existe no
Mape, caso não exista, definir um valor padrão - A proposta de "upsert" do ECMAScript chegou ao Stage 4, adicionando dois novos métodos a
MapeWeakMapgetOrInsert: se a chave não existir, insere e retorna o valor padrão especificadogetOrInsertComputed: quando o custo de gerar o valor padrão for alto, permite cálculo sob demanda via callback- O callback recebe a chave como argumento, então também pode ser usado para gerar valores padrão com base nela
- Foi adicionado à lib
esnext, então já pode ser usado imediatamente no TypeScript 6.0 - Implementado com contribuição de Renegade334 neste PR
RegExp.escape
- A função
RegExp.escape, que escapa caracteres especiais em expressões regulares, chegou ao Stage 4 - Está incluída na lib
es2025e pode ser usada no TypeScript 6.0 - Implementado com contribuição de Kenta Moriuchi neste PR
Integração de dom.iterable e dom.asynciterable à lib dom
- Antes, para usar iteração em
NodeList,HTMLCollectionetc., era preciso declarar"lib": ["dom", "dom.iterable"] - No TypeScript 6.0, o conteúdo de
lib.dom.iterable.d.tselib.dom.asynciterable.d.tsfoi integrado por completo alib.dom.d.tsdom.iterableedom.asynciterableainda podem ser referenciados, mas agora são arquivos vazios
- Como todos os principais navegadores modernos já oferecem suporte a isso, a mudança melhora a conveniência e elimina um ponto comum de confusão
Principais mudanças de valores padrão
strictcom padrãotrue: como a maioria dos novos projetos deseja o modo strict, projetos que dependiam do padrão anteriorfalseagora precisam definir explicitamente"strict": falsemodulecom padrãoesnext: reflete a realidade de o ESM ter se tornado o formato de módulo dominantetargetcom padrão na versão ES mais recente (atualmentees2025): como runtimes evergreen se tornaram comuns, o transpile para versões antigas deixou de ser necessárionoUncheckedSideEffectImportscom padrãotrue: ajuda a detectar typos em imports usados apenas por efeitos colateraislibReplacementcom padrãofalse: melhora o desempenho padrão ao evitar falhas desnecessárias de resolução de módulos e o aumento do conjunto observado
rootDir passa a ter . como padrão
- Antes, quando não especificado, seu valor era inferido como o diretório comum de todos os arquivos de entrada não declarativos
- Isso criava o problema de precisar carregar e fazer parse do projeto para decidir se um arquivo pertencia a ele
- No TypeScript 6.0, o valor padrão fica fixo no diretório onde está o
tsconfig.json - Se os arquivos-fonte estiverem em um nível mais profundo que o
tsconfig.json, será necessário configurar explicitamente algo como"rootDir": "./src"- Caso contrário, pode surgir uma estrutura de saída inesperada, como
./dist/src/index.js
- Caso contrário, pode surgir uma estrutura de saída inesperada, como
types passa a ter [] como padrão
- Antes, todos os pacotes em
node_modules/@typeseram incluídos automaticamente, gerando grande overhead no tempo de build- Em muitos repositórios, centenas de pacotes
@typesacabam sendo incluídos transitivamente
- Em muitos repositórios, centenas de pacotes
- No TypeScript 6.0, o padrão passa a ser
[](array vazio), evitando o carregamento de arquivos de declaração desnecessários - Já foram observados casos de melhoria real de 20% a 50% no tempo de build
- Na maioria dos projetos, será necessário definir explicitamente algo como
"types": ["node"]ou"types": ["node", "jest"]- É possível restaurar o comportamento anterior com
"types": ["*"]
- É possível restaurar o comportamento anterior com
Itens descontinuados (Deprecation)
Descontinuação de target: es5
- O target ES5 quase não tem mais casos de uso devido à aposentadoria do IE e à universalização dos navegadores evergreen
- O target mínimo passa a ser ES2015; se for necessário gerar saída ES5, recomenda-se usar um compilador externo
Descontinuação de --downlevelIteration
- Como só tinha efeito no emit para ES5, perde a razão de existir com a descontinuação do target ES5
Descontinuação de --moduleResolution node (node10)
- Refletia o algoritmo de resolução de módulos do Node.js 10, que não corresponde ao comportamento das versões atuais do Node.js
- Recomenda-se migrar para
nodenext(alvo direto do Node.js) oubundler(uso com bundlers/Bun)
Descontinuação dos valores de módulo AMD, UMD e SystemJS
--module amd,--module umd,--module systemjse--module nonedeixam de ser suportados- Como o ESM é amplamente suportado em navegadores e no Node.js, é necessário migrar para bundlers ou para target ESM
Descontinuação de --baseUrl
- Era usado principalmente como prefixo de
paths, mas também funcionava como raiz de lookup da resolução de módulos, o que podia causar resolução de caminhos não intencional - A migração consiste em remover
baseUrle adicionar o prefixo diretamente nos itens depaths- Ex.:
"@app/*": ["app/*"]→"@app/*": ["./src/app/*"]
- Ex.:
Descontinuação de --moduleResolution classic
- Era o algoritmo original de resolução de módulos do TypeScript, e hoje todos os casos práticos podem ser substituídos por
nodenextoubundler
Descontinuação de esModuleInterop false e allowSyntheticDefaultImports false
- Não será mais possível definir essas duas opções como
false, então o comportamento seguro de interop ficará sempre ativado - Será necessário ajustar, por exemplo,
import * as express from "express"paraimport express from "express"
Descontinuação de --alwaysStrict false
- Todo código passa a ser tratado como JavaScript strict mode, então códigos que usem
await,static,privateetc. como identificadores comuns precisarão renomeá-los
Descontinuação de outFile
- Era um recurso para combinar vários arquivos de entrada em um só, mas foi substituído por bundlers externos como Webpack, Rollup, esbuild e Vite
- A decisão foi tomada para focar o TypeScript em seu papel central de checagem de tipos e emit de declarações
Descontinuação da sintaxe legada module (declaração de namespace)
- A sintaxe
module Foo { ... }foi descontinuada de forma definitiva, sendo necessário usarnamespace Foo { ... } - Declarações de módulos ambient no formato
declare module "some-module" { ... }continuam suportadas - O objetivo é evitar conflito com a proposta de blocos
moduledo ECMAScript
Descontinuação da palavra-chave import asserts
- Será necessário mudar de
import ... asserts { type: "json" }paraimport ... with { type: "json" } - Isso acompanha a mudança da proposta de import assertions para a proposta de import attributes (palavra-chave
with)
Descontinuação da diretiva no-default-lib
/// <reference no-default-lib="true"/>deixa de ser suportado; recomenda-se usar--noLibou--libReplacement
Erro ao especificar arquivos pela linha de comando quando existe tsconfig.json
- Ao executar
tsc foo.ts, se houver umtsconfig.jsonno mesmo diretório, ocorrerá erro - É possível ignorá-lo explicitamente com a flag
--ignoreConfig
Preparação para o TypeScript 7.0
- As opções descontinuadas no 6.0 ainda podem ser usadas sem erro com
"ignoreDeprecations": "6.0", mas serão removidas por completo no 7.0 - É possível ajustar automaticamente itens como
baseUrlerootDircom a ferramenta ts5to6 - O TypeScript 7.0 tem lançamento previsto para os próximos meses e já vem sendo adotado amplamente em grandes bases de código dentro e fora da Microsoft
- Feedback é encorajado por meio do build nightly native preview e da extensão para VS Code
3 comentários
Estou ansioso pelo momento em que a transição completa para um compilador baseado em Go acontecer!
Ué? O TypeScript vai mudar depois para um nativo baseado em Go?
Só o compilador.