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

BASH
# Automatically Generate Default Configuration
tsc --init

# Generate a detailed configuration with comments
tsc --init --typescript

(2) Estrutura básica

JSON
{
  "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:

JSON
{
  "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
💡 Dica: A opção 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

JSON
{
  "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

JSON
{
  "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:

JSON
{
  "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.
💡 Dica: O 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

JSON
{
  "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

JSON
{
  "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

TYPESCRIPT
// 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
}
📌 Recomendação: Ative 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

TYPESCRIPT
// 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;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
// Executed successfully


4. Configuração de módulos e caminhos

(1) Mapeamento de caminhos

JSON
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@utils/*": ["src/utils/*"],
      "@components/*": ["src/components/*"]
    }
  }
}

(2) resolveJsonModule

JSON
{
  "compilerOptions": {
    "resolveJsonModule": true,
    "esModuleInterop": true
  }
}
TYPESCRIPT
// Import Allowed JSON Documents
import config from "./config.json";
console.log(config.port);  // ✅

(3) allowJs com checkJs

JSON
{
  "compilerOptions": {
    "allowJs": true,    // Allow compilation JS Documents
    "checkJs": false    // Do not check JS File Type(Compile Only)
  }
}
💡 Objetivo: Ao migrar gradualmente um projeto de JS para TS, comece ativando o allowJs para permitir que TS e JS coexistam e, em seguida, adicione tipos aos poucos.



5. Opções de qualidade do código

JSON
{
  "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

TYPESCRIPT
// 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

JSON
{
  "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)

JSON
{
  "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)

JSON
{
  "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

TYPESCRIPT
// 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}!`;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
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

TYPESCRIPT
// 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
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Alice

❓ Perguntas Frequentes

P: O strict torna 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 o strict desde 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 o noImplicitAny, depois o strictNullChecks e, por fim, ative o strict por completo.

P: O que é o noEmit? Por que o projeto Vite foi criado? R: O noEmit: true permite 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 o tsc --noEmit para 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 extends para herança de configuração? R: Quando um projeto possui vários arquivos tsconfig (por exemplo, front-end, scripts Node e testes), use extends para compartilhar a configuração básica e sobrescrever apenas as diferenças. O tsconfig.node.json pode extends o tsconfig.json, modificando apenas opções como target e module. Isso evita a duplicação da configuração.

📖 Resumo

📝 Exercícios

  1. Exercício básico (Dificuldade ⭐): Use tsc --init para gerar o arquivo padrão tsconfig.json, altere target para ES2020, habilite strict e defina outDir como dist. Crie um arquivo simples em TypeScript, compile-o e verifique se ele funciona.
  2. Exercício avançado (Dificuldade ⭐⭐): Configure um arquivo tsconfig.json que suporte o alias de caminho @/*src/*. Crie src/utils/math.ts e src/main.ts e use o alias para importar funções de math.ts para main.ts.
  3. 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) e packages/server/tsconfig.json (estende a base, back-end Node) — e use references para vincular os dois subprojetos.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%