Também disponível em: English · Español · Français · العربية
O que o modo strict do TypeScript liga de verdade
As nove opções que o strict cobre, as oito que não, e o código que cada uma deixa passar — conferido compilando, não citando.
O que o strict: true faz?
Colocar strict como true no tsconfig é um atalho: ele liga um grupo fixo de opções individuais do compilador, não é uma verificação em si. No TypeScript 5.9 esse grupo tem exatamente nove membros — noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, strictBuiltinIteratorReturn, noImplicitThis, useUnknownInCatchVariables e alwaysStrict.
Vale ler essa lista no compilador e não num artigo, porque ela cresce. O strictBuiltinIteratorReturn entrou no TypeScript 5.6 e a maioria dos textos ainda descreve o strict como sete ou oito opções. Esta página tira a lista das declarações de opções do próprio compilador, então ela segue o TypeScript e não o contrário.
O que importa é o que não está no grupo. O TypeScript tem outras oito opções que pegam erros reais e que o strict não toca — entre elas noUncheckedIndexedAccess, exactOptionalPropertyTypes e noImplicitOverride. Um projeto com strict ligado não é um projeto com todas as verificações ligadas, e a diferença é maior do que quase todo mundo espera.
Como usar
- Cole seu tsconfig, ou só o bloco compilerOptions. Comentários e vírgulas sobrando não são problema: um tsconfig é JSONC, não JSON, e isto lê do jeito que o tsc lê. Serve tanto o arquivo inteiro quanto um objeto de opções solto.
- Veja as duas contagens. Quantas das nove cobertas pelo strict estão ligadas, e quantas das oito que ele não cobre. O que você desligou na mão aparece à parte, porque o explícito vence o strict e ninguém te avisa.
- Olhe os exemplos de código das oito. Cada um é um programa que compila limpo com o strict ligado e falha assim que aquela opção entra. Copie a configuração mais estrita no botão se quiser as dezessete.
As oito verificações que o strict deixa de fora
Cada opção dessa segunda lista vem aqui com um programa que demonstra a lacuna, e cada um desses programas foi compilado duas vezes na construção desta página: uma com o strict, onde não pode produzir erro algum, e outra com a opção adicionada, onde precisa falhar. Um exemplo só aparece porque o compilador deu os dois resultados, então a afirmação é uma medição e não uma opinião.
A primeira que a gente encontra é a noUncheckedIndexedAccess. Com o strict, ler xs[0] de um array de strings devolve uma string, mesmo que o array possa estar vazio e o valor possa ser undefined — a indexação simplesmente mente sobre isso. Ligar a opção transforma o tipo em string | undefined e o compilador passa a pedir a verificação. É a maior fonte de undefined em tempo de execução em bases de código que no resto são estritas.
A exactOptionalPropertyTypes é a mais sutil. Com um tipo { nickname?: string }, o strict aceita numa boa { nickname: undefined } — some a diferença entre uma propriedade ausente e uma presente valendo undefined, o que importa muitíssimo se aquele objeto vai ser serializado ou espalhado sobre uma linha de banco. A noImplicitOverride pega o método de uma subclasse que encobre o do pai sem querer, que é como um rename deixa de chamar em silêncio o que você achava. A noPropertyAccessFromIndexSignature devolve env.DATABASE_URL para env["DATABASE_URL"], então um erro de digitação no nome de uma variável de ambiente deixa de passar como string.
As quatro restantes têm menos a ver com tipos e mais com código morto ou inalcançável: um case de switch que vaza para o seguinte, uma função que devolve valor num caminho e nada no outro, e locais ou parâmetros que ninguém lê.
Limites honestos
O explícito vence o strict, nos dois sentidos, e essa é a parte que morde em silêncio. Escrever strict como true junto de noImplicitAny como false realmente silencia os erros de any implícito: o compilador aceita a combinação sem dizer nada, e uma configuração herdada de um projeto antigo pode carregar um furo desses por anos. Esta página lista esses casos à parte, e o tsc --showConfig confirma se você quiser uma segunda opinião.
Ela não segue o extends. Um tsconfig que herda de um arquivo base — o preset de um framework, um pacote compartilhado — é só metade da história, e esta página lê o que você cola em vez de resolver a cadeia. Rode tsc --showConfig no projeto para ver o resultado resolvido e cole aquilo aqui.
A lista está presa a uma versão do TypeScript, mostrada ao lado do botão de copiar. Opções são acrescentadas: se o seu compilador for mais novo que o desta página, ele pode conhecer alguma que não está aqui. É por isso que a lista é gerada do compilador em vez de digitada, e por isso a versão fica na página em vez de ficar subentendida.
E ligar tudo não é automaticamente o certo. A noUnusedLocals em especial briga com trabalho em andamento, e vários times a mantêm no editor e não no build. A página mostra onde você está e quanto custa cada opção; ela não finge que a resposta é sempre sim.
Por que é grátis?
Tudo acontece no seu navegador. Um tsconfig pode citar caminhos internos, registries de pacotes e a estrutura do projeto, e nada disso é enviado a lugar nenhum — o arquivo não sai da aba.
Não há custo de servidor a recuperar, então não há cadastro, nem limite, nem marca d’água.