TypeScript Academy · Lektion

Result/Either-liknande typer

Modellera framgång och misslyckanden explicit med en Result/Either-union, lägg till hjälpfunktioner (map/flatMap/mapError) och håll flöden förutsägbara utan try/catch överallt.

Lektion 1 av 28 steg

Result/Either-liknande typer är en gratis lektion i TypeScript Academy på CoddyKit. Detta är lektion 1 av 2. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för TypeScript Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i TypeScript Academy innehåller totalt 2 lektioner.

Introduktion

Mål: Göra fel synliga. Ni kommer att modellera resultat med en diskriminerad union, komponera med hjälpfunktioner och konvertera undantag vid gränsen.

  • Resultattyp
  • map/flatMap/mapError
  • HTTP-integrering

Resultatets kärna

Skapa ett litet Result-verktyg: konstruktorerna ok/err samt map, flatMap och mapError för komposition.

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

Domänfel

Modellera domänfel som en diskriminerad union med en tag. Varje gren innehåller precisa data för tydliga meddelanden.

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

Komponera flöden

Komponera valideringar med flatMap. Använd en switch med en never-kontroll för att säkerställa fullständighet vid kompileringen.

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

Undantag → Result

Fånga undantag vid I/O-gränser och omvandla dem till Result. Anroparna får då en enda felväg att hantera.

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

Tips för HTTP-mappning

HTTP-integrering: mappa domänfel till 400/409 och I/O-undantag till 502/503. Håll mapper-funktionen liten så att kontrollerna förblir rena och förutsägbara.

Kontroll av nyttan med Result

Snabb kontroll: Varför föredra en diskriminerad Result-union?

Sammanfattning

Sammanfattning: Definiera en liten Result-typ, komponera med map/flatMap, modellera domänfel som unioner och konvertera undantag vid gränserna.

Gratis att börja

Lär dig TypeScript med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
101
Lektioner
352

Vanliga frågor

Är lektionen ”Result/Either-liknande typer” gratis?

Ja – hela texten till ”Result/Either-liknande typer” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i TypeScript Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i TypeScript Academy innehåller totalt 2 lektioner.

Vad lär jag mig i ”Result/Either-liknande typer”?

Modellera framgång och misslyckanden explicit med en Result/Either-union, lägg till hjälpfunktioner (map/flatMap/mapError) och håll flöden förutsägbara utan try/catch överallt. Ni övar på TypeScript Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig TypeScript Academy?

Du behöver inga förkunskaper. Utbildningen i TypeScript Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 2.

Hur lång tid tar lektionen ”Result/Either-liknande typer”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här TypeScript Academy-lektionen?

Ja. Varje TypeScript Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Result/Either-liknande typer
  2. Fullständig felhantering med diskriminerade unioner
← Tillbaka till TypeScript Academy