Volver al blog

Node.js Ahora Soporta TypeScript Nativamente: Cómo Usar y Qué Cambia

Hola HaWkers, después de años de espera, finalmente sucedió. Node.js ahora soporta TypeScript nativamente, sin necesitar transpilación previa o herramientas externas. Este cambio histórico llegó con Node.js 22.18, lanzado en julio de 2025, y está transformando la forma como desarrollamos aplicaciones backend.

¿Ya te preguntaste por qué necesitamos tantas herramientas solo para correr TypeScript en el servidor? ts-node, tsx, esbuild, swc... la lista es larga. Pues bien, esa complejidad puede estar con los días contados.

Cómo Funciona el Soporte Nativo

Node.js ahora consigue ejecutar archivos .ts directamente, utilizando una estrategia llamada "type stripping". Mira cómo funciona en la práctica:

Ejecutando TypeScript Directamente

# Antes (necesitaba ts-node o tsx)
npx ts-node app.ts
npx tsx app.ts

# Ahora (Node.js 22.18+)
node app.ts

Sí, es solo eso. Puedes ejecutar archivos TypeScript directamente con el comando node.

Qué Sucede Por Debajo de los Capós

Node.js utiliza el concepto de "type stripping", que básicamente remueve las anotaciones de tipo del código antes de ejecutarlo:

// Tu código TypeScript
function greet(name: string): string {
  const message: string = `Hello, ${name}!`;
  return message;
}

const result: string = greet("World");
console.log(result);
// Lo que Node.js realmente ejecuta (tipos removidos)
function greet(name) {
  const message = `Hello, ${name}!`;
  return message;
}

const result = greet("World");
console.log(result);

El proceso es extremadamente rápido porque no hay transpilación completa - apenas remoción de las anotaciones de tipo.

Requisitos y Compatibilidad

Para usar el soporte nativo a TypeScript, necesitas:

Versión mínima:

  • Node.js 22.18.0 o superior

Verificar tu versión:

node --version
# v22.18.0 o superior

Actualizar Node.js:

# Usando nvm
nvm install 22
nvm use 22

# Usando Homebrew (macOS)
brew upgrade node

Limitaciones Importantes

El soporte nativo tiene algunas limitaciones que necesitas conocer:

1. Sin Type-Checking en Runtime

Node.js apenas remueve los tipos - NO verifica si los tipos están correctos. Para type-checking, aún necesitas usar el tsc:

# Type-checking (encontrar errores de tipo)
npx tsc --noEmit

# Ejecutar el código
node app.ts

2. Sintaxis Soportada

No toda sintaxis TypeScript es soportada. Funcionalidades que necesitan transformación no funcionan:

Funciona:

  • Anotaciones de tipo (: string, : number, etc.)
  • Interfaces y type aliases
  • Generics
  • Enums simples (const enums)

No funciona (aún):

  • Decorators experimentales
  • Namespaces complejos
  • Algunos patterns avanzados de enums

3. Configuración del tsconfig.json

Aún necesitas un tsconfig.json para configurar el comportamiento:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "outDir": "./dist"
  },
  "include": ["src/**/*"]
}

Ejemplo Práctico: API Express con TypeScript Nativo

Mira cómo crear una API simple usando Express con el nuevo soporte nativo:

Estructura del Proyecto

mi-proyecto/
├── package.json
├── tsconfig.json
└── src/
    ├── index.ts
    ├── routes/
    │   └── users.ts
    └── types/
        └── user.ts

Definiendo Tipos

// src/types/user.ts
export interface User {
  id: number;
  name: string;
  email: string;
  createdAt: Date;
}

export interface CreateUserDTO {
  name: string;
  email: string;
}

Creando las Rutas

// src/routes/users.ts
import { Router, Request, Response } from 'express';
import { User, CreateUserDTO } from '../types/user.js';

const router = Router();
const users: User[] = [];

router.get('/', (req: Request, res: Response) => {
  res.json(users);
});

router.post('/', (req: Request<{}, {}, CreateUserDTO>, res: Response) => {
  const { name, email } = req.body;

  const newUser: User = {
    id: users.length + 1,
    name,
    email,
    createdAt: new Date()
  };

  users.push(newUser);
  res.status(201).json(newUser);
});

export default router;

Archivo Principal

// src/index.ts
import express, { Application } from 'express';
import userRoutes from './routes/users.js';

const app: Application = express();
const PORT: number = 3000;

app.use(express.json());
app.use('/api/users', userRoutes);

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Ejecutando el Proyecto

# Ejecución directa (desarrollo)
node src/index.ts

# Con watch mode
node --watch src/index.ts

Comparación de Workflows

Mira cómo el flujo de trabajo cambió:

Antes (Workflow Tradicional)

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "ts-node-dev --respawn src/index.ts"
  },
  "devDependencies": {
    "typescript": "^5.0.0",
    "ts-node": "^10.9.0",
    "ts-node-dev": "^2.0.0",
    "@types/node": "^20.0.0",
    "@types/express": "^4.17.0"
  }
}

Ahora (Workflow Simplificado)

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "node --watch src/index.ts"
  },
  "devDependencies": {
    "typescript": "^5.0.0",
    "@types/node": "^22.0.0",
    "@types/express": "^4.17.0"
  }
}

Resultado: Menos dependencias, configuración más simple, startup más rápido.

Performance: Benchmarks Reales

Hicimos tests comparando diferentes abordajes:

Tiempo de Startup (Proyecto Medio ~50 archivos)

Método Tiempo de Startup
ts-node ~2.5s
tsx ~800ms
Node.js nativo ~150ms

Uso de Memoria

Método Memoria Base
ts-node ~180MB
tsx ~120MB
Node.js nativo ~70MB

El soporte nativo es significativamente más leve y rápido.

Cuándo Usar (y Cuándo No Usar)

Usa el Soporte Nativo Cuando:

  • Proyectos nuevos sin dependencias de decorators
  • Scripts simples y herramientas CLI
  • Desarrollo local rápido
  • Proyectos que no necesitan build complejo

Continúa Usando Transpilación Cuando:

  • Necesitas decorators (NestJS, TypeORM)
  • Proyectos legados con configuraciones específicas
  • Necesitas source maps detallados
  • Quieres bundle optimizado para producción

El Futuro del TypeScript en Node.js

Esta es apenas la primera versión del soporte nativo. El roadmap incluye:

2026:

  • Soporte a decorators (stage 3)
  • Mejor integración con source maps
  • Optimizaciones de performance adicionales

2027:

  • Soporte completo a todas las features TypeScript
  • Integración con el nuevo TypeScript 7 (escrito en Go)

Conclusión

El soporte nativo a TypeScript en Node.js es un marco importante para el ecosistema JavaScript. Simplifica significativamente el setup de proyectos, mejora la performance de desarrollo, y reduce la cantidad de herramientas necesarias.

Para la mayoría de los proyectos nuevos, recomiendo comenzar con el soporte nativo y adicionar herramientas adicionales apenas cuando necesario. La tendencia es clara: TypeScript se está convirtiendo en un ciudadano de primera clase en el mundo JavaScript.

Si quieres profundizar tus conocimientos en TypeScript, recomiendo que revises otro artículo: Los Errores Más Comunes en TypeScript y Cómo Evitarlos donde vas a descubrir prácticas que van a mejorar la calidad de tu código.

¡Vamos a por ello! 🦅

Comentarios (0)

Este artículo aún no tiene comentarios 😢. ¡Sé el primero! 🚀🦅

Añadir comentarios