Introducción: por qué TypeScript y REST API son la pareja ideal para el desarrollo rápido
\nEl desarrollo web moderno exige velocidad y fiabilidad. Si necesita crear rápidamente un backend para una aplicación móvil, un servicio web o una arquitectura de microservicios, la combinación TypeScript + Node.js + Express es una de las herramientas más eficaces. TypeScript añade tipado estricto a JavaScript, lo que permite detectar errores en la fase de compilación, no en tiempo de ejecución. Esto es especialmente valioso al construir una API REST, donde cada endpoint debe saber con claridad qué datos recibe y devuelve.
\nEn este artículo, crearemos en 30 minutos una API REST completa para gestionar una lista de tareas (To-Do List). Aprenderá a configurar el proyecto, escribir controladores, rutas y middleware. Todo con ejemplos prácticos y código listo para usar.
\n\nPreparación y configuración del proyecto (5 minutos)
\nPrimero, crearemos la estructura del proyecto e instalaremos las dependencias.
\nmkdir todo-api\ncd todo-api\nnpm init -y\nnpm install express cors uuid\nnpm install -D typescript @types/express @types/cors @types/uuid ts-node nodemon\nCree el archivo tsconfig.json en la raíz del proyecto:
{\n "compilerOptions": {\n "target": "ES2020",\n "module": "commonjs",\n "outDir": "./dist",\n "rootDir": "./src",\n "strict": true,\n "esModuleInterop": true,\n "skipLibCheck": true\n },\n "include": ["src/**/*"]\n}\nAgregue los scripts en package.json:
"scripts": {\n "dev": "nodemon --exec ts-node src/index.ts",\n "build": "tsc",\n "start": "node dist/index.js"\n}\nCree la carpeta src y el archivo index.ts — el punto de entrada.
Estructura básica de carpetas
\n- \n
src/index.ts— punto de entrada, inicio del servidor \n src/routes/tasks.ts— rutas para las tareas \n src/controllers/taskController.ts— lógica de procesamiento de solicitudes \n src/models/task.ts— interfaces y tipos \n src/middleware/errorHandler.ts— manejo de errores (opcional) \n
Creación del modelo de datos e interfaces (5 minutos)
\nDefinamos los tipos de datos para nuestra tarea. Cree el archivo src/models/task.ts:
export interface Task {\n id: string;\n title: string;\n completed: boolean;\n createdAt: Date;\n}\n\nexport type CreateTaskDto = Pick<Task, 'title'>;\nexport type UpdateTaskDto = Partial<Pick<Task, 'title' | 'completed'>>;\nAquí usamos Pick y Partial — tipos utilitarios incorporados de TypeScript. CreateTaskDto acepta solo el título, mientras que UpdateTaskDto acepta campos opcionales para una actualización parcial.
Escritura de controladores y rutas (15 minutos)
\nAhora viene lo más interesante: la lógica de la aplicación. Crearemos un almacenamiento temporal de tareas en memoria (in-memory storage). Para producción, debe reemplazarse por una base de datos.
\n\nControlador de tareas
\nArchivo src/controllers/taskController.ts:
import { Request, Response } from 'express';\nimport { v4 as uuidv4 } from 'uuid';\nimport { Task, CreateTaskDto, UpdateTaskDto } from '../models/task';\n\n// Almacenamiento temporal\nlet tasks: Task[] = [];\n\n// GET /api/tasks\nexport const getAllTasks = (req: Request, res: Response) => {\n res.json(tasks);\n};\n\n// GET /api/tasks/:id\nexport const getTaskById = (req: Request, res: Response) => {\n const task = tasks.find(t => t.id === req.params.id);\n if (!task) {\n return res.status(404).json({ message: 'Tarea no encontrada' });\n }\n res.json(task);\n};\n\n// POST /api/tasks\nexport const createTask = (req: Request, res: Response) => {\n const { title } = req.body as CreateTaskDto;\n if (!title || typeof title !== 'string') {\n return res.status(400).json({ message: 'El campo title es obligatorio y debe ser una cadena' });\n }\n