Verificación de tipos en CI
Ejecutar tsc --noEmit en CI detecta errores de tipo que ESLint por sí solo pasa por alto y bloquea las fusiones antes de que las compilaciones rotas lleguen a producción.
Receta
Tarjeta de receta de referencia rápida: lista para copiar y pegar.
{
"scripts": {
"typecheck": "tsc --noEmit -p tsconfig.json"
}
}- run: npm ci
- run: npm run typecheckCuándo usarlo:
- Cada servicio o biblioteca de Node en TypeScript.
- Omites la emisión en CI (
noEmit) para una retroalimentación más rápida que unabuildcompleta. - Los monorepos necesitan verificación de tipos por paquete o una solución raíz.
Ejemplo de trabajo
// 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 buildLo que esto demuestra:
typecheckse ejecuta antes de las pruebas para fallar en segundos ante errores de firma.strict: trueno es negociable para los servicios de backend.buildtodavía se ejecuta en CI para verificar la configuración de emisión y la salida dedist/.
Análisis profundo
Cómo funciona
tsc --noEmitverifica los tipos sin escribir archivos, ideal como puerta de fusión en CI.- Un
tsconfig.build.jsonseparado emite solosrc/para los paquetes de producción. skipLibCheck: trueacelera la CI al omitir la validación de.d.tsennode_modules.- Monorepos:
turbo run typecheckcondependsOn: ["^build"]cuando los tipos provienen de dependencias compiladas.
Orden de CI
| Paso | Por qué este orden |
|---|---|
npm ci | Grafo determinista |
typecheck | Señal rápida sobre tipos |
lint | Lógica y estilo |
test | Comportamiento |
build | Verificación de emisión |
Notas de TypeScript
{
"compilerOptions": {
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}- Se pueden habilitar banderas más estrictas en toda la organización una vez que el código base esté limpio.
- Alinea
@types/nodecon Node 24.
Errores comunes
- Solo ejecutar build en CI - La falta de la ruta
noEmitoculta errores de tipo solo de prueba sibuildexcluyetest/. Solución:typecheckdedicado que incluya pruebas. - Verificación de tipos sin construir dependencias del espacio de trabajo - Las aplicaciones fallan por la falta de
.d.tsde los paquetes. Solución:turbo run typecheck --filter=api...después de^build. - Diferente tsconfig localmente vs CI - El editor usa la solución; CI usa el proyecto incorrecto. Solución: documentar
npm run typecheckcomo fuente de verdad. skipLibCheckocultando anulaciones incorrectas - Raro pero doloroso. Solución: ejecución local periódica conskipLibCheck: falseen las actualizaciones.- Ignorar errores de tipo en las pruebas -
@ts-expect-errorsin comentarios se acumula. Solución: lint prohíbe directivas excesivas de expect-error.
Alternativas
| Alternativa | Cuándo usar | Cuándo NO usar |
|---|---|---|
tsgo / vista previa nativa | Experimentando con la velocidad | CI de producción necesita TSC estable |
| Solo ESLint con reconocimiento de tipos | Complemento, no reemplazo | Omites tsc por completo |
build como única puerta | Scripts pequeños de un solo archivo | Pruebas excluidas de la configuración de compilación |
Preguntas frecuentes
¿Debería la verificación de tipos incluir archivos de prueba?
Sí, a menos que las pruebas usen un tsconfig.test.json separado referenciado por un segundo paso de CI.
¿Qué tan rápida es la verificación de tipos en monorepos?
Usa referencias de proyecto y el almacenamiento en caché de Turbo. Verifica los tipos de los paquetes en orden de dependencia una vez, almacena los hashes en caché.
¿NestJS necesita banderas especiales?
Nest usa tsconfig.build.json con emitDecoratorMetadata. La verificación de tipos debe usar la misma configuración de experimentalDecorators que la compilación.
¿Puedo paralelizar la verificación de tipos y el linting?
Sí, en trabajos de CI separados después de npm ci. Ambos deben pasar antes de la fusión.
¿Qué hay de JavaScript checkJs?
allowJs + checkJs para una migración gradual. Prefiere TS completo para nuevos servicios.
¿Debería CI almacenar en caché tsc incremental?
--incremental con .tsbuildinfo en caché ayuda a grandes repositorios; Turbo a menudo es suficiente.
¿Cómo afectan los alias de ruta a CI?
Los paths de tsconfig deben coincidir con el tiempo de ejecución (o usar nombres de paquetes construidos). Los alias desalineados pasan localmente con tsx pero fallan tsc.
¿Es necesaria la verificación de tipos si se ejecuta la compilación?
Sí, cuando build include es más estrecho que typecheck. Las pruebas y los scripts permanecen cubiertos.
¿Cómo controlamos las actualizaciones de estrictos?
Habilita una nueva bandera por sprint con un problema de seguimiento; CI lo aplica una vez que no hay errores.
¿Express@5 necesita @types/express?
Express 5 incluye tipos; elimina @types/express duplicado si ambos están instalados.
Relacionado
- Conceptos básicos de Linting - ESLint complementa tsc
- Mejores prácticas de Linting - pila completa de puertas de calidad
- knip y Código Muerto - detección de exportaciones no utilizadas
Versiones de la pila: Esta página fue escrita para Node.js 24.18.0 (LTS activa), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 y NestJS 11.