0Pricing
TypeScript Academy · Lesson

Modeling Result Types

Represent success and failure as data with Result.

Modeling Result Types is a free TypeScript Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The Result Type

A Result models an operation that either succeeds with a value or fails with an error, as a discriminated union you can return instead of throwing.

Defining Result

The classic shape uses an ok discriminant. When ok is true there is a value; when false there is an error.

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

Constructor Helpers

Small ok and err helpers make building results concise and readable, instead of writing the object literals by hand each time.

const ok = <T>(value: T): Result<T, never> => ({ ok: true, value });
const err = <E>(error: E): Result<never, E> => ({ ok: false, error });

Returning a Result

A fallible function returns ok(value) or err(error). The return type advertises both possibilities to every caller.

function divide(a: number, b: number): Result<number, string> {
  return b === 0 ? err("divide by zero") : ok(a / b);
}

Narrowing on ok

Checking result.ok narrows the union. Inside the true branch TypeScript knows value exists; inside the false branch it knows error exists.

const r = divide(10, 2);
if (r.ok) console.log(r.value); // 5
else console.log(r.error);

The Discriminant Drives Safety

The ok field is the discriminant that lets the compiler pick the right branch. You cannot access value without proving ok is true first.

const r = divide(1, 0);
// r.value here is a type error until we check r.ok
if (!r.ok) console.log("err:", r.error);

Typed Errors

Errors can be richer than strings. Using a typed error union lets callers handle each kind precisely after narrowing.

type DivErr = { kind: "zero" } | { kind: "overflow" };
function div(a: number, b: number): Result<number, DivErr> {
  if (b === 0) return err({ kind: "zero" });
  return ok(a / b);
}

Exhaustive Error Handling

Because the error type is a union, a switch on its discriminant can be checked for exhaustiveness, ensuring every failure mode is handled.

const r = div(1, 0);
if (!r.ok) {
  switch (r.error.kind) {
    case "zero": console.log("no zero"); break;
    case "overflow": console.log("too big"); break;
  }
}

A Default-Value Helper

Sometimes you just want the value or a fallback. A small unwrapOr reads cleanly and keeps the failure handling local.

function unwrapOr<T, E>(r: Result<T, E>, fallback: T): T {
  return r.ok ? r.value : fallback;
}
console.log(unwrapOr(divide(1, 0), -1)); // -1

Result vs Throwing

Result moves failure into the return type, so callers must engage with it. The trade-off is more explicit code, which is usually worth it for expected errors.

A Complete Example

Putting it together: define helpers, return results, and narrow before use. The compiler guarantees the error branch is acknowledged.

function safeParse(s: string): Result<number, string> {
  const n = Number(s);
  return Number.isNaN(n) ? err("NaN") : ok(n);
}
const p = safeParse("42");
console.log(p.ok ? p.value : p.error); // 42

Quick Check

Quick check on this lesson.

Recap

Result<T, E> is a discriminated union { ok: true; value } or { ok: false; error }. Build it with ok/err helpers and narrow on ok to safely access value or error, with typed errors enabling exhaustive handling.

Frequently asked questions

Is the “Modeling Result Types” lesson free?

Yes — the full text of “Modeling Result Types” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.

What will I learn in “Modeling Result Types”?

Represent success and failure as data with Result. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start TypeScript Academy?

No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Modeling Result Types” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this TypeScript Academy lesson?

Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. The Problem with Throwing Errors
  2. Modeling Result Types
  3. Option and Maybe Types
  4. Railway-Oriented Programming
← Back to TypeScript Academy