TypeScript: Uma explicação detalhada do arquivo…
Última atualização: 2026-08-26
O tsconfig.json é o centro de configuração dos projetos em TypeScript — ele informa ao compilador como compilar o código, verificar os tipos e gerar os resultados. Compreender essas opções de configuração é essencial para garantir que seu projeto em TypeScript funcione sem problemas.
1. Noções básicas sobre o tsconfig.json
(1) Criar um arquivo de configuração
# Automatically Generate Default Configuration
tsc --init
# Generate a detailed configuration with comments
tsc --init --typescript
(2) Estrutura básica
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
(3) Campos de nível superior
| Campo | Descrição |
|---|---|
compilerOptions |
Opções do compilador |
include |
Arquivos incluídos (modo glob) |
exclude |
Arquivos excluídos |
files |
Lista de arquivos explicitamente especificados |
references |
Referências do projeto (monorepo) |
extends |
Herdar de outro arquivo de configuração |
2. Opções de compilação do núcleo
(1) destino — destino de compilação
Especifique a versão do JavaScript compilado:
{
"compilerOptions": {
"target": "ES2020"
}
}
| Valor | Descrição | Cenários recomendados |
|---|---|---|
"ES5" |
Compatível com navegadores mais antigos | Compatível com o IE11 |
"ES2018" |
Navegadores modernos | Projetos gerais da Web |
"ES2020" |
Recursos mais recentes da versão estável | Recomendado |
"ESNext" |
Novidades sobre propostas | Projetos de ponta |
target afeta apenas a transformação de sintaxe (por exemplo, funções-seta → funções comuns); ela não afeta a verificação de tipos. A verificação de tipos é controlada pela opção lib.
(2) módulo — Sistema de Módulos
{
"compilerOptions": {
"module": "ESNext"
}
}
| Valor | Descrição | Cenários recomendados |
|---|---|---|
"CommonJS" |
Padrão do Node.js | Projeto Node |
"ESNext" / "ES2015" |
Módulos ES | Navegador/Deno/Vite |
"UMD" |
Módulos de uso geral | Lançamentos da biblioteca |
"System" |
SystemJS | Carregador de módulos legados |
(3) moduleResolution — Estratégia de resolução de módulos
{
"compilerOptions": {
"moduleResolution": "node"
}
}
| Valor | Descrição |
|---|---|
"node" |
Estilo Node.js (recomendado) |
"classic" |
Estilo TS antigo (não recomendado) |
"bundler" |
Vite/esbuild e outras ferramentas de compilação (TS 5.0+) |
(4) lib — Biblioteca de tipos
Especifique as declarações de tipos embutidos disponíveis:
{
"compilerOptions": {
"lib": ["ES2020", "DOM", "DOM.Iterable"]
}
}
| Valor | Tipo fornecido |
|---|---|
"ES2020" |
Promise, Array.flat, BigInt, etc. |
"DOM" |
documento, janela, HTMLElement, etc. |
"DOM.Iterable" |
NodeList 's para...of |
"ES2020.String" |
Métodos para strings no ES2020 |
"ES2020.Promise" |
Promise.allSettled, etc. |
target inclui automaticamente o lib correspondente. Se você especificar explicitamente um lib, ele não será mais incluído automaticamente — será necessário listar manualmente todas as bibliotecas necessárias. Projetos web geralmente exigem o ["ES2020", "DOM"].
(5) outDir e rootDir
{
"compilerOptions": {
"outDir": "./dist", // Compilation Output Directory
"rootDir": "./src", // Source Code Root Directory(Preserve the directory structure)
"declaration": true, // Generate .d.ts Statement
"sourceMap": true // Generate .js.map Source Code Mapping
}
}
3. Opção de modo estrito
(1) Modo estrito totalmente ativado
{
"compilerOptions": {
"strict": true
}
}
strict: true equivale a ativar todas as opções a seguir ao mesmo tempo:
| Opção | Descrição |
|---|---|
strictNullChecks |
não é possível atribuir nulo/indefinido a outros tipos |
strictFunctionTypes |
Verificação inversa dos parâmetros de uma função |
strictBindCallApply |
Verificação rigorosa de bind/call/apply |
strictPropertyInitialization |
As propriedades da classe devem ser inicializadas |
noImplicitAny |
Implícito any proibido |
noImplicitThis |
Proibir o uso implícito de “this” como “any” |
alwaysStrict |
Emitir “use strict” |
(2) Compreendendo cada ponto
// strictNullChecks: true
let name: string = null; // ❌ null Cannot be assigned string
let name2: string | null = null; // ✅ Explicit Declaration
// noImplicitAny: true
function greet(name) { // ❌ The parameter is implicitly set to any
return name;
}
function greet2(name: string) { // ✅ Explicit Annotation
return name;
}
// strictPropertyInitialization: true
class User {
name: string; // ❌ Property not initialized
age: number = 0; // ✅ Has an initial value
}
strict em todos os novos projetos. Essa é a base da segurança de tipos do TypeScript — embora possa exigir um pouco mais de esforço para adicionar anotações de tipo inicialmente, isso ajuda a evitar um grande número de erros em tempo de execução.
▶ Exemplo: Comparação antes e depois do modo estrito
// strict: false — the following code does not generate any errors, but it may crash during execution.
let name: string = null as any; // Runtime name.toUpperCase() Breakdown
function greet(user) { // user Implicit any
return user.name; // No type checking
}
// strict: true — captured at compile time
let name2: string | null = null; // ✅ Must be explicitly declared null
function greet2(user: { name: string }) { // ✅ Parameters must be labeled
return user.name;
}
Saída:
// Executed successfully
4. Configuração de módulos e caminhos
(1) Mapeamento de caminhos
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@utils/*": ["src/utils/*"],
"@components/*": ["src/components/*"]
}
}
}
(2) resolveJsonModule
{
"compilerOptions": {
"resolveJsonModule": true,
"esModuleInterop": true
}
}
// Import Allowed JSON Documents
import config from "./config.json";
console.log(config.port); // ✅
(3) allowJs com checkJs
{
"compilerOptions": {
"allowJs": true, // Allow compilation JS Documents
"checkJs": false // Do not check JS File Type(Compile Only)
}
}
allowJs para permitir que TS e JS coexistam e, em seguida, adicione tipos aos poucos.
5. Opções de qualidade do código
{
"compilerOptions": {
"noUnusedLocals": true, // Error: Unused local variables
"noUnusedParameters": true, // Error: Unused function parameters
"noImplicitReturns": true, // Error: Function branch does not return a value
"noFallthroughCasesInSwitch": true, // Error: switch fallthrough
"forceConsistentCasingInFileNames": true // File names must be case-sensitive
}
}
(1) Demonstração
// noUnusedLocals: true
let unused = 42; // ❌ Unused variables
// noUnusedParameters: true
function handler(event: Event) { // ❌ event Unused
console.log("Trigger");
}
// Fix: Use _ prefix tag
function handler2(_event: Event) { // ✅ _ The prefix does not cause an error
console.log("Trigger");
}
// noImplicitReturns: true
function getGrade(score: number): string {
if (score >= 90) return "A";
if (score >= 80) return "B";
// ❌ Missing else Branched return
}
// noFallthroughCasesInSwitch: true
switch (action) {
case "create":
createItem();
// ❌ Missing break——case Penetration
case "update":
updateItem();
break;
}
6. Modelos de configuração comuns
(1) Projeto de back-end em Node.js
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"moduleResolution": "node",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
(2) Projeto de front-end em React (Vite)
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": { "@/*": ["src/*"] }
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
(3) Projetos de bibliotecas (publicação de pacotes npm)
{
"compilerOptions": {
"target": "ES2018",
"module": "ESNext",
"moduleResolution": "node",
"declaration": true,
"declarationDir": "./dist/types",
"outDir": "./dist/esm",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
▶ Exemplo: Efeitos da configuração target e module
// The same source code compiles differently based on target/module settings
async function fetchData(): Promise<string> {
let response = await Promise.resolve("hello");
return response.toUpperCase();
}
export function greet(name: string): string {
return `Hello, ${name}!`;
}
Saída:
Compilation output varies by target/module — see explanations below
With "target": "ES5", async/await compiles to a verbose state machine;
with "target": "ES2020", it stays as native async/await.
With "module": "CommonJS", exports become exports.greet = greet;
with "module": "ESNext", they remain as export function greet.
▶ Exemplo: Verificações estritas de null na prática
// strictNullChecks: true prevents common null bugs
interface User { name: string; email: string | null; }
function getDisplayName(user: User): string {
// return user.email.toLowerCase(); // ❌ Object is possibly null
return user.email ? user.email.toLowerCase() : user.name; // ✅
}
function findUser(id: number): User | null {
return id > 0 ? { name: "Alice", email: "a@b.com" } : null;
}
let user = findUser(1);
// console.log(user.name); // ❌ user is possibly null
if (user) {
console.log(user.name); // ✅ narrowed to User
}
Saída:
Alice
❓ Perguntas Frequentes
P: O
stricttorna a escrita de código mais difícil? R: Inicialmente, pode exigir mais anotações de tipo (especialmente para verificações de nulo), mas, a longo prazo, reduz significativamente os erros em tempo de execução. Recomendamos ativar ostrictdesde o início — assim que você se acostumar, vai até achar estranho não usá-lo. Se o seu projeto já for grande, você pode ativá-lo gradualmente: primeiro ative onoImplicitAny, depois ostrictNullCheckse, por fim, ative ostrictpor completo.
P: O que é o noEmit? Por que o projeto Vite foi criado? R: O
noEmit: truepermite que o TypeScript realize apenas a verificação de tipos, sem gerar arquivos JS. O projeto Vite utiliza o Vite (esbuild) para compilação e empacotamento, enquanto o tsc é responsável apenas pela verificação de tipos — portanto, não há necessidade de o tsc gerar arquivos. Use otsc --noEmitpara a verificação de tipos na CI e deixe que o Vite cuide da compilação em tempo real durante o desenvolvimento.
P: O skipLibCheck deve ser ativado? R: Recomendamos ativá-lo. O skipLibCheck ignora a verificação de tipos para arquivos
.d.ts, o que pode acelerar significativamente a compilação. A desvantagem é que ele pode deixar passar erros em declarações de tipos de terceiros — mas o risco é extremamente baixo (o pacote @types é revisado pela comunidade). Ativar o skipLibCheck em projetos grandes pode economizar 30% ou mais no tempo de compilação.
P: Qual é o objetivo de usar
extendspara herança de configuração? R: Quando um projeto possui vários arquivostsconfig(por exemplo, front-end, scripts Node e testes), useextendspara compartilhar a configuração básica e sobrescrever apenas as diferenças. Otsconfig.node.jsonpodeextendsotsconfig.json, modificando apenas opções comotargetemodule. Isso evita a duplicação da configuração.
📖 Resumo
tsconfig.jsoné o centro de configuração para projetos em TypeScript — ele contém três campos principais:compilerOptions,includeeexcludetargetcontrola a versão do JavaScript,modulecontrola o sistema de módulos elibcontrola as bibliotecas de tipos disponíveisstrict: trueAtivar todas as verificações rigorosas — deve estar ativado para novos projetos- O mapeamento de caminhos (baseUrl + paths) usa aliases para substituir caminhos absolutos longos
- As opções de qualidade de código (como noUnusedLocals e noImplicitReturns) foram aprimoradas ainda mais
- Diferentes tipos de projeto têm modelos de configuração recomendados distintos — back-end em Node, front-end em React e projetos de bibliotecas
📝 Exercícios
- Exercício básico (Dificuldade ⭐): Use
tsc --initpara gerar o arquivo padrãotsconfig.json, alteretargetpara ES2020, habilitestricte definaoutDircomodist. Crie um arquivo simples em TypeScript, compile-o e verifique se ele funciona. - Exercício avançado (Dificuldade ⭐⭐): Configure um arquivo
tsconfig.jsonque suporte o alias de caminho@/*→src/*. Criesrc/utils/math.tsesrc/main.tse use o alias para importar funções demath.tsparamain.ts. - Desafio (Dificuldade: ⭐⭐⭐): Projete uma hierarquia de configuração para um projeto monorepo — base
tsconfig.base.json(opções compartilhadas),packages/app/tsconfig.json(estende a base, front-end React) epackages/server/tsconfig.json(estende a base, back-end Node) — e usereferencespara vincular os dois subprojetos.