0Pricing
TypeScript Academy · Lección

Tipos con estilo Result/Either

Modele explícitamente el éxito y el fallo con una unión Result/Either, añada helpers (map/flatMap/mapError) y mantenga flujos predecibles sin usar try/catch en todas partes.

Tipos con estilo Result/Either es una lección gratuita de TypeScript Academy en CoddyKit. Esta es la lección 1 de 2. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de TypeScript Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de TypeScript Academy incluye 2 lecciones en total.

Introducción

Objetivo: hacer que los fallos sean visibles. Modelará los resultados con una unión discriminada, compondrá operaciones con ayudantes y convertirá las excepciones en la frontera.

  • Tipo Result
  • map/flatMap/mapError
  • Integración con HTTP

Núcleo de Result

Cree una pequeña utilidad Result: constructores ok/err y también map, flatMap y mapError para la composición.

export type Ok<T>  = { ok: true;  value: T }
export type Err<E> = { ok: false; error: E }
export type Result<T, E> = Ok<T> | Err<E>

export const ok = <T>(value: T): Ok<T> => ({ ok: true, value })
export const err = <E>(error: E): Err<E> => ({ ok: false, error })

export function map<T, E, U>(r: Result<T, E>, f: (t: T) => U): Result<U, E> {
  return r.ok ? ok(f(r.value)) : r
}
export function flatMap<T, E, U>(r: Result<T, E>, f: (t: T) => Result<U, E>): Result<U, E> {
  return r.ok ? f(r.value) : r
}
export function mapError<T, E, F>(r: Result<T, E>, g: (e: E) => F): Result<T, F> {
  return r.ok ? r : err(g(r.error))
}

Errores de dominio

Modele los errores de dominio como una unión discriminada con un tag. Cada rama contiene datos precisos para generar buenos mensajes.

export type CreateUserError =
  | { tag: "InvalidEmail"; detail?: string }
  | { tag: "Duplicate"; email: string }

export function validateEmail(email: string): Result<string, CreateUserError> {
  const okEmail = /.+@.+/.test(email)
  return okEmail ? ok(email.toLowerCase()) : err({ tag: "InvalidEmail", detail: "bad format" })
}

const existing = new Set(["ada@example.com"]) // pretend DB
export function saveUser(email: string): Result<{ id: string }, CreateUserError> {
  if (existing.has(email)) return err({ tag: "Duplicate", email })
  return ok({ id: Math.random().toString(36).slice(2) })
}

Composición de flujos

Componga las validaciones con flatMap. Use un switch con una comprobación de never para imponer la exhaustividad en tiempo de compilación.

export function createUser(flowEmail: string) {
  return flatMap(validateEmail(flowEmail), email => saveUser(email))
}

// Use
const r = createUser("Ada@example.com")
if (r.ok) {
  console.log("id:", r.value.id)
} else {
  switch (r.error.tag) {
    case "InvalidEmail": console.error("invalid email:", r.error.detail); break
    case "Duplicate": console.error("already used:", r.error.email); break
    default: ((x: never) => x)(r.error) // exhaustiveness
  }
}

Excepción → Result

En los límites de E/S, envuelva las excepciones y conviértalas en Result. Los llamadores dispondrán de una única ruta de errores que gestionar.

export async function fromPromise<T>(p: Promise<T>): Promise<Result<T, { tag: "Exception"; message: string }>> {
  try { return ok(await p) }
  catch (e) { return err({ tag: "Exception", message: e instanceof Error ? e.message : String(e) }) }
}

// Example: wrap a fetch
export async function fetchJson<T>(url: string): Promise<Result<T, { tag: "Exception"; message: string }>> {
  return fromPromise(fetch(url).then(r => r.json() as T))
}

Consejos para la asignación HTTP

Integración con HTTP: asigne los errores de dominio a 400/409 y las excepciones de E/S a 502/503. Mantenga una pequeña función de asignación para que los controladores sigan siendo claros y predecibles.

Comprobación del beneficio de Result

Comprobación rápida: ¿Por qué es preferible una unión discriminada Result?

Resumen

Resumen: Defina un tipo Result pequeño, componga con map/flatMap, modele los errores de dominio como uniones y convierta las excepciones en las fronteras.

Preguntas frecuentes

¿La lección «Tipos con estilo Result/Either» es gratis?

Sí — el texto completo de «Tipos con estilo Result/Either» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de TypeScript Academy, actualiza a CoddyKit PRO. El curso de TypeScript Academy incluye 2 lecciones en total.

¿Qué aprenderé en «Tipos con estilo Result/Either»?

Modele explícitamente el éxito y el fallo con una unión Result/Either, añada helpers (map/flatMap/mapError) y mantenga flujos predecibles sin usar try/catch en todas partes. Practicas TypeScript Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar TypeScript Academy?

No se requiere experiencia previa. TypeScript Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 2.

¿Cuánto tiempo toma la lección «Tipos con estilo Result/Either»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de TypeScript Academy?

Sí. Cada lección de TypeScript Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Tipos con estilo Result/Either
  2. Manejo exhaustivo de errores con uniones discriminadas
← Volver a TypeScript Academy