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.
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.
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
- Result/Either-liknande typer
- Fullständig felhantering med diskriminerade unioner