0Pricing
TypeScript Academy · Aula

Tipos no estilo Result/Either

Modele explicitamente sucesso e falha com uma união Result/Either, adicione auxiliares (map/flatMap/mapError) e mantenha os fluxos previsíveis sem usar try/catch em toda parte.

Tipos no estilo Result/Either é uma aula grátis de TypeScript Academy no CoddyKit. Esta é a aula 1 de 2. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de TypeScript Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de TypeScript Academy inclui 2 aulas no total.

Introdução

Objetivo: Tornar as falhas visíveis. Você modelará resultados com uma união discriminada, fará composição com auxiliares e converterá exceções na fronteira.

  • Tipo Resultado
  • map/flatMap/mapError
  • Integração HTTP

Núcleo de Resultado

Crie um pequeno utilitário de Resultado: construtores ok/err e também map, flatMap e mapError para composição.

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))
}

Erros de domínio

Modele erros de domínio como uma união discriminada com uma tag. Cada ramo contém dados precisos para produzir boas mensagens.

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) })
}

Composição de fluxos

Faça a composição das validações com flatMap. Use um switch com uma verificação de never para impor a exaustividade em tempo de compilação.

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
  }
}

Exceção → Resultado

Nas fronteiras de E/S, encapsule as exceções e converta-as em Result. Os chamadores mantêm um único caminho de erro para tratar.

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))
}

Dicas de mapeamento HTTP

Integração HTTP: mapeie erros de domínio para 400/409 e exceções de E/S para 502/503. Mantenha uma pequena função de mapeamento para que os controladores permaneçam limpos e previsíveis.

Verificação do benefício de Resultado

Verificação rápida: Por que preferir uma união discriminada de Resultado?

Recapitulação

Recapitulação: Defina um pequeno tipo Resultado, faça a composição com map/flatMap, modele os erros de domínio como uniões e converta as exceções nas fronteiras.

Perguntas Frequentes

A aula “Tipos no estilo Result/Either” é grátis?

Sim — o texto completo de “Tipos no estilo Result/Either” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de TypeScript Academy, atualize para CoddyKit PRO. O curso de TypeScript Academy inclui 2 aulas no total.

O que vou aprender em “Tipos no estilo Result/Either”?

Modele explicitamente sucesso e falha com uma união Result/Either, adicione auxiliares (map/flatMap/mapError) e mantenha os fluxos previsíveis sem usar try/catch em toda parte. Você pratica TypeScript Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar TypeScript Academy?

Nenhuma experiência prévia é necessária. TypeScript Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 2.

Quanto tempo leva a aula “Tipos no estilo Result/Either”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de TypeScript Academy?

Sim. Cada aula de TypeScript Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Tipos no estilo Result/Either
  2. Tratamento exaustivo de erros com uniões discriminadas
← Voltar para TypeScript Academy