Verificação de Tipos no CI
Executar tsc --noEmit no CI captura erros de tipo que o ESLint sozinho não detecta e bloqueia merges antes que builds quebrados cheguem à produção.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
{
"scripts": {
"typecheck": "tsc --noEmit -p tsconfig.json"
}
}- run: npm ci
- run: npm run typecheckQuando usar isso:
- Todo serviço ou biblioteca Node.js com TypeScript.
- Se você pula a emissão no CI (
noEmit) para um feedback mais rápido que umbuildcompleto. - Monorepos que precisam de verificação de tipo por pacote ou solução raiz.
Exemplo de Trabalho
// tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"noEmit": true,
"skipLibCheck": true,
"types": ["node"]
},
"include": ["src", "test"]
}// package.json
{
"scripts": {
"typecheck": "tsc --noEmit",
"build": "tsc -p tsconfig.build.json"
}
}# .github/workflows/ci.yml
name: ci
on: [pull_request]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "24.18.0"
cache: npm
- run: npm ci
- run: npm run typecheck
- run: npm run lint
- run: npm test
- run: npm run buildO que isso demonstra:
typechecké executado antes dos testes para falhar em segundos em erros de assinatura.strict: trueé inegociável para serviços de backend.buildainda é executado no CI para verificar a configuração de emissão e a saídadist/.
Mergulho Profundo
Como Funciona
tsc --noEmitverifica tipos sem escrever arquivos - um portão de merge ideal para CI.tsconfig.build.jsonseparado emite apenassrc/para bundles de produção.skipLibCheck: trueacelera o CI pulando a validação de.d.tsemnode_modules.- Monorepos:
turbo run typecheckcomdependsOn: ["^build"]quando os tipos vêm de dependências compiladas.
Ordem do CI
| Etapa | Por que essa ordem |
|---|---|
npm ci | Grafo determinístico |
typecheck | Sinal rápido sobre tipos |
lint | Lógica e estilo |
test | Comportamento |
build | Verificação de emissão |
Notas do TypeScript
{
"compilerOptions": {
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}- Flags mais rigorosas podem ser habilitadas em toda a organização assim que a base de código estiver limpa.
- Alinhe
@types/nodecom Node 24.
Armadilhas
- Executar apenas build no CI - O caminho
noEmitausente oculta erros de tipo apenas de teste sebuildexcluirtest/. Correção:typecheckdedicado incluindo testes. - Verificação de tipos sem construir dependências do workspace - Aplicativos falham em
.d.tsausentes de pacotes. Correção:turbo run typecheck --filter=api...após^build. tsconfigdiferente localmente vs CI - O editor usa a solução; o CI usa o projeto errado. Correção: documentarnpm run typecheckcomo fonte da verdade.skipLibCheckocultando substituições incorretas - Raro, mas doloroso. Correção: execução local periódica comskipLibCheck: falseem atualizações.- Ignorando erros de tipo em testes -
@ts-expect-errorsem comentários se acumula. Correção: lint proíbe diretivasexpect-errorexcessivas.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
tsgo / preview nativo | Experimentando velocidade | CI de produção precisa de TSC estável |
| Apenas ESLint ciente de tipos | Complemento, não substituto | Você pula tsc inteiramente |
build como único portão | Scripts minúsculos de arquivo único | Testes excluídos da configuração de build |
FAQs
A verificação de tipos deve incluir arquivos de teste?
Sim, a menos que os testes usem um tsconfig.test.json separado referenciado por uma segunda etapa do CI.
Quão rápida é a verificação de tipos em monorepos?
Use referências de projeto e cache do Turbo. Verifique tipos de pacotes em ordem de dependência uma vez, armazene hashes em cache.
O NestJS precisa de flags especiais?
Nest usa tsconfig.build.json com emitDecoratorMetadata. A verificação de tipos deve usar as mesmas configurações de experimentalDecorators do build.
Posso paralelizar typecheck e lint?
Sim, em trabalhos de CI separados após npm ci. Ambos devem passar antes do merge.
E quanto ao `checkJs` do JavaScript?
allowJs + checkJs para migração gradual. Prefira TS completo para novos serviços.
O CI deve armazenar em cache o tsc incremental?
--incremental com .tsbuildinfo em cache ajuda repositórios grandes; Turbo geralmente é suficiente.
Como os aliases de caminho afetam o CI?
Os paths do tsconfig devem corresponder ao runtime (ou usar nomes de pacotes compilados). Aliases desalinhados passam localmente com tsx, mas falham em tsc.
A verificação de tipos é necessária se o build for executado?
Sim, quando o include do build é mais restrito que o typecheck. Testes e scripts permanecem cobertos.
Como definimos um portão para atualizações de rigor?
Habilite uma nova flag por sprint com um problema de rastreamento; o CI a impõe assim que não houver erros.
O express@5 precisa de @types/express?
Express 5 envia tipos; remova @types/express duplicado se ambos estiverem instalados.
Relacionado
- Noções Básicas de Linting - ESLint complementa o tsc
- Melhores Práticas de Linting - pilha completa de portões de qualidade
- knip & Código Morto - detecção de exportações não utilizadas
Versões da Stack: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.