
Mejora la legibilidad y mantenibilidad de tu código en TypeScript con el patrón Early Return
¿Alguna vez has tenido un if anidado tan profundo como la Fosa de las Marianas? 😅 Esto es más común de lo que crees, especialmente cuando entras a un desarrollo meses después y tienes que agregar nuevas reglas de negocio.
¿Qué es el patrón Early Return?
El patrón early return (retorno anticipado) es una técnica en la que una función retorna un valor tan pronto como se detecta una condición que hace innecesario continuar ejecutando el resto de su lógica.
En lugar de anidar if-else
profundamente, se evalúan primero los casos en los que no se requiere seguir adelante.
Beneficios:
Mejora la legibilidad, al evitar múltiples niveles de indentación.
Mejora la mantenibilidad, al hacer cada condición más clara y explícita.
Facilita el control del flujo, la depuración y las pruebas.
Ejemplo básico
Versión tradicional (con if-else
anidados):
1const addTwoIntegers = (a: number, b: number): number => {
2 let result: number;
3 if (Number.isInteger(a) && Number.isInteger(b)) {
4 if (a > 0 && b > 0) {
5 result = a + b;
6 } else {
7 throw new Error("Ambos números deben ser positivos.");
8 }
9 } else {
10 throw new Error("Ambos argumentos deben ser enteros.");
11 }
12 return result;
13};
Esto funciona, pero se vuelve difícil de leer conforme aumentan las condiciones
Con Early Return:
1const addTwoIntegers = (a: number, b: number): number => {
2 if (!Number.isInteger(a) || !Number.isInteger(b)) {
3 throw new Error("Ambos argumentos deben ser enteros.");
4 }
5 if (a <= 0 || b <= 0) {
6 throw new Error("Ambos números deben ser positivos.");
7 }
8 return a + b;
9};
Mucho más limpio, con un flujo claro y plano
Ejemplo avanzado: procesamiento de datos
Sin early return (versión tradicional):
1const getUserEmails = (users: { email?: string }[]): string[] => {
2 let emails: string[] = [];
3 if (users.length > 0) {
4 for (const user of users) {
5 if (user.email) {
6 if (/^\S+@\S+\.\S+$/.test(user.email)) {
7 emails.push(user.email);
8 } else {
9 throw new Error("Email inválido encontrado.");
10 }
11 } else {
12 throw new Error("Falta la propiedad 'email' en un usuario.");
13 }
14 }
15 } else {
16 throw new Error("La lista de usuarios está vacía.");
17 }
18 return emails;
19};
Con early return:
1const getUserEmails = (users: { email?: string }[]): string[] => {
2 if (users.length === 0) {
3 throw new Error("La lista de usuarios está vacía.");
4 }
5 return users.map((user) => {
6 if (!user.email) {
7 throw new Error("Falta la propiedad 'email' en un usuario.");
8 }
9 if (!/^\S+@\S+\.\S+$/.test(user.email)) {
10 throw new Error("Email inválido encontrado.");
11 }
12 return user.email;
13 });
14};
El flujo principal queda claro: validar, luego mapear. Las condiciones de error están separadas y explícitas.
Cuándo no es buena idea usar Early Return
Demasiados
if
seguidos pueden complicar la lectura si las condiciones están relacionadas.En funciones muy breves, puede no aportar beneficios reales.
Si se requiere un solo
return
por control o por pruebas, múltiplesreturn
pueden ser problemáticos.
Buenas prácticas al usar Early Return
Agrupa al inicio los casos de error o valores inválidos.
Deja el flujo principal para el final.
Combínalo con tipado estricto (TypeScript) para evitar errores en ejecución.
Usa mensajes de error claros y específicos.
Conclusión
El patrón early return no es exclusivo de ningún lenguaje. Aplicarlo ayuda a que tu código sea más claro, menos complejo y más fácil de mantener. Ideal tanto para refactors como para futuros desarrolladores que lo lean.