Manejo de errores en TypeScript: try/catch, clases personalizadas y tipado estricto

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: Por qué el manejo de errores en TypeScript no es solo try/catch

TypeScript añade tipado estático a JavaScript, pero los errores en tiempo de ejecución (runtime errors) siguen siendo parte de cualquier aplicación. A diferencia de JS puro, donde catch(e) devuelve any, TypeScript ofrece mecanismos más estrictos. El manejo correcto de errores no solo previene caídas, sino que también crea un sistema comprensible para depuración y mantenimiento del código. En este artículo analizaremos todos los aspectos: desde el try/catch básico hasta la creación de jerarquías personalizadas de errores con tipado completo.



1. Sintaxis básica de try/catch y el problema del tipo unknown

Estructura clásica

La estructura básica en TypeScript se ve igual que en JavaScript:

try {    // Código que puede lanzar una excepción    const data = JSON.parse('{"name": "TypeScript"}');    console.log(data.name);} catch (error) {    // Manejo del error    console.error('Ocurrió un error:', error);}

Sin embargo, hay una diferencia importante: en TypeScript la variable error en el bloque catch tiene tipo unknown (no any, como en JavaScript, a menos que se especifique lo contrario). Esto se hizo por seguridad de tipos.



El problema con unknown y cómo resolverlo

El tipo unknown significa que no podemos simplemente acceder a las propiedades del error, por ejemplo, error.message. El compilador dará un error:

catch (error) {    // Error TS2571: Object is of type 'unknown'.    console.log(error.message); // ❌ No compilará}

Para acceder a las propiedades, necesitamos reducir el tipo:

catch (error) {    if (error instanceof Error) {        console.log(error.message); // ✅ Funciona    } else {        console.log('Error desconocido:', error);    }}

O usar una verificación de existencia de propiedad:

catch (error) {    if (error && typeof error === 'object' && 'message' in error) {        console.log((error as { message: string }).message);    }}


2. Creación de clases de error personalizadas con tipado

¿Por qué es importante?

El Error estándar solo contiene name, message y stack. En proyectos reales a menudo se necesitan campos adicionales: código de error, estado HTTP, datos para registro. TypeScript permite crear una jerarquía de clases de error con soporte completo de tipos.



Ejemplo de clase personalizada

// Clase base para todos los errores de la aplicaciónclass AppError extends Error {    public readonly statusCode: number;    public readonly isOperational: boolean;

constructor(message: string, statusCode: number = 500, isOperational: boolean = true) { super(message); this.name = 'AppError'; this.statusCode = statusCode; this.isOperational = isOperational; // Restauramos el prototipo (necesario para TypeScript) Object.setPrototypeOf(this, new.target.prototype); }}

// Errores especializadosclass NotFoundError extends AppError { constructor(resource: string) { super(`${resource} no encontrado`, 404); this.name = 'NotFoundError'; }}

class ValidationError extends AppError { public readonly errors: string[];

constructor(errors: string[]) { super('Error de validación', 400); this.name = 'ValidationError'; this.errors = errors; }}


Uso con try/catch

function getUser(id: number): User {    if (id <= 0) {        throw new ValidationError(['El ID debe ser un número positivo']);    }    // ... lógica para obtener usuario    if (!user) {        throw new NotFoundError('Usuario');    }    return user;}

try { const user = getUser(-1);} catch (error) { if (err

Blogs

Book Recommendations