Usar TypeScript con Node.js requiere algunas decisiones de configuración que no son evidentes la primera vez: cómo instalar los tipos de Node, cómo ejecutar código TypeScript en desarrollo sin compilar, la elección entre ESM y CommonJS, y cómo tipar las variables de entorno. Esta guía cubre todo el proceso desde cero con las herramientas más habituales en 2026.
Instalación básica
npm init -y npm install --save-dev typescript @types/node npx tsc --init
El paquete @types/node añade los tipos de todas las APIs de Node.js: fs, path, http, process, Buffer, etc. Sin él, TypeScript no sabe qué es process.env o require.
tsconfig para Node.js
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "dist",
"rootDir": "src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"declaration": true,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Desarrollo con tsx: ejecutar sin compilar
En desarrollo, compilar con tsc y ejecutar el resultado es tedioso. tsx es la herramienta más rápida en 2026 para ejecutar TypeScript directamente en Node.js:
npm install --save-dev tsx npx tsx src/index.ts # O con watch mode: npx tsx watch src/index.ts
Alternativas: ts-node (más lento, usa el compilador de TypeScript), ts-node-esm para ESM. tsx usa esbuild internamente y es mucho más rápido que ts-node en proyectos grandes.
ESM vs CommonJS en Node.js
La elección entre ESM y CommonJS afecta al tsconfig y al package.json. Para ESM:
// package.json
{
"type": "module",
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "tsx watch src/index.ts"
}
}
Con "module": "NodeNext" y ESM, los imports deben incluir la extensión .js (no .ts): TypeScript compila ./usuario.ts a ./usuario.js y los imports deben referenciar el fichero de salida:
// Con NodeNext y ESM: extensión explícita .js
import { crearUsuario } from "./usuario.js";
Tipar process.env
Por defecto, process.env tiene tipo Record<string, string | undefined>. Para tipar las variables de entorno específicas de tu proyecto, extiende la interfaz ProcessEnv:
// src/types/env.d.ts
declare namespace NodeJS {
interface ProcessEnv {
readonly NODE_ENV: "development" | "production" | "test";
readonly DATABASE_URL: string;
readonly API_KEY: string;
readonly PORT?: string;
}
}
// Ahora TypeScript conoce los tipos de las variables const puerto = parseInt(process.env.PORT ?? "3000", 10); const dbUrl: string = process.env.DATABASE_URL; // string (no string | undefined)
Path aliases y estructura de proyecto
Para proyectos medianos y grandes, los path aliases evitan las importaciones relativas largas:
// tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}
Estructura de proyecto recomendada para un servidor Node.js TypeScript:
proyecto/ ??? src/ ? ??? index.ts # punto de entrada ? ??? config/ # configuración y variables de entorno ? ??? modelos/ # interfaces y tipos de datos ? ??? servicios/ # lógica de negocio ? ??? controladores/ # handlers de rutas ? ??? repositorios/ # acceso a datos ? ??? types/ # declaraciones globales (.d.ts) ??? dist/ # código compilado (en .gitignore) ??? tsconfig.json ??? package.json
Imagen: Pexels / Pixabay
