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 ✅