Volver a TypeScript Intermedio
tsconfig y Configuración del Proyecto
Un tsconfig.json bien configurado detecta más errores, habilita mejores herramientas y controla la salida del compilador.
Opciones Clave del Compilador
{
"compilerOptions": {
// ── Salida ────────────────────────────────────────────────
"target": "ES2022", // Versión de JS a la que compilar
"module": "ESNext", // Sistema de módulos
"lib": ["ES2022", "DOM"], // Definiciones de tipos integradas
"outDir": "./dist",
"rootDir": "./src",
// ── Strictness ───────────────────────────────────────────
"strict": true, // Habilita todos los flags estrictos
// "strictNullChecks": true // null/undefined deben manejarse
// "strictFunctionTypes": true // Verificación más estricta de tipos de función
// "noImplicitAny": true // Sin tipos 'any' implícitos
// "noImplicitThis": true // Sin 'this' implícito
// ── Importaciones ────────────────────────────────────────
"moduleResolution": "Bundler", // Mejor para Vite / bundlers modernos
"esModuleInterop": true, // import React from 'react' (sin * as)
"resolveJsonModule": true, // import data from './data.json'
"baseUrl": ".",
"paths": {
"@/*": ["src/*"] // Alias: import { X } from '@/components/X'
},
// ── Calidad ──────────────────────────────────────────────
"noUnusedLocals": true, // Error en variables no usadas
"noUnusedParameters": true, // Error en parámetros no usados
"noImplicitReturns": true, // Todos los caminos deben retornar un valor
"exactOptionalPropertyTypes": true, // undefined !== propiedad ausente
// ── Emisión ──────────────────────────────────────────────
"declaration": true, // Generar archivos .d.ts
"sourceMap": true, // Generar source maps
"skipLibCheck": true // Omitir verificación de tipos en node_modules
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
Referencias de Proyecto (Monorepos)
Divide un proyecto grande en piezas más pequeñas compiladas independientemente:
packages/
├── shared/
│ ├── src/
│ └── tsconfig.json { "composite": true }
├── api/
│ ├── src/
│ └── tsconfig.json { "references": [{ "path": "../shared" }] }
└── web/
├── src/
└── tsconfig.json { "references": [{ "path": "../shared" }] }
Compilar con: tsc --build (solo recompila lo que cambió)
Variables de Entorno Seguras en Tipos
// src/env.ts — validar al iniciar la aplicación
const variablesRequeridas = ['DATABASE_URL', 'JWT_SECRET', 'PORT'] as const;
function cargarEnv(): Record<typeof variablesRequeridas[number], string> {
const faltantes = variablesRequeridas.filter(clave => !process.env[clave]);
if (faltantes.length > 0) {
throw new Error(`Variables de entorno faltantes: ${faltantes.join(', ')}`);
}
return Object.fromEntries(
variablesRequeridas.map(clave => [clave, process.env[clave]!])
) as Record<typeof variablesRequeridas[number], string>;
}
export const env = cargarEnv();
// env.DATABASE_URL — string tipado, validado al iniciar
Guardias de Tipo y Funciones de Aserción
// Función guardia de tipo
function esUsuario(valor: unknown): valor is Usuario {
return (
typeof valor === 'object' &&
valor !== null &&
typeof (valor as any).id === 'number' &&
typeof (valor as any).nombre === 'string'
);
}
// Función de aserción (lanza si es inválido)
function afirmarUsuario(valor: unknown): asserts valor is Usuario {
if (!esUsuario(valor)) {
throw new TypeError('Se esperaba un objeto Usuario');
}
}
const datos: unknown = await fetch('/api/usuario').then(r => r.json());
afirmarUsuario(datos); // Lanza si es inválido
console.log(datos.nombre); // TypeScript sabe que es Usuario ✅