0Pricing
TypeScript Academy · Lesson

Railway-Oriented Programming

Chain operations that may fail without try/catch.

Railway-Oriented Programming is a free TypeScript Academy lesson on CoddyKit — lesson 4 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 Railway Metaphor

Railway-oriented programming pictures a computation as two parallel tracks: a success track and a failure track. Once you switch to failure, you stay there, skipping the rest.

Chaining Result Functions

Each step takes a value and returns a Result. We want to connect steps so that the first failure short-circuits the chain and is carried to the end.

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

map: Transform the Success Value

map applies a plain function to the value when the Result is ok, and passes failures through unchanged. It stays on the success track.

function map<T, U, E>(r: Result<T, E>, f: (t: T) => U): Result<U, E> {
  return r.ok ? ok(f(r.value)) : r;
}
console.log(map(ok(2), n => n + 1)); // { ok: true, value: 3 }

flatMap: Chain Fallible Steps

When the next step itself returns a Result, use flatMap (also called andThen). It avoids nesting Results and short-circuits on failure.

function flatMap<T, U, E>(r: Result<T, E>, f: (t: T) => Result<U, E>): Result<U, E> {
  return r.ok ? f(r.value) : r;
}

Why flatMap Not map

If you used map with a Result-returning function you would get Result<Result<U,E>,E>. flatMap flattens that one level, keeping a single Result.

Short-Circuiting on First Error

As soon as a step returns err, every later flatMap passes it through untouched. The remaining steps never run, exactly like switching to the failure track.

const start = err("boom") as Result<number, string>;
const out = flatMap(start, n => ok(n + 1));
console.log(out); // { ok: false, error: "boom" }

Building a Pipeline

Compose validation steps, each returning a Result. The first failure becomes the pipeline's result; if all pass, the success value flows to the end.

function parseNum(s: string): Result<number, string> {
  const n = Number(s);
  return Number.isNaN(n) ? err("not a number") : ok(n);
}
function positive(n: number): Result<number, string> {
  return n > 0 ? ok(n) : err("must be positive");
}

Running the Pipeline

Chaining flatMap threads the value through each fallible step. A failure anywhere stops the chain and surfaces that error.

const good = flatMap(parseNum("5"), positive);
console.log(good); // { ok: true, value: 5 }
const bad = flatMap(parseNum("-3"), positive);
console.log(bad); // { ok: false, error: "must be positive" }

Combining map and flatMap

Use flatMap for steps that can fail and map for pure transforms. Together they keep the happy path linear and the errors automatic.

const result = map(flatMap(parseNum("10"), positive), n => n * 2);
console.log(result); // { ok: true, value: 20 }

No try/catch Needed

The whole pipeline expresses success and failure through values. There is no try/catch, and the type of every step makes the error path explicit and unavoidable.

Why It Scales

Railway-oriented code keeps complex workflows readable: each step is small and pure, errors propagate automatically, and adding a step does not complicate existing error handling.

Quick Check

Quick check on this lesson.

Recap

Railway-oriented programming chains Result-returning steps with map (transform success) and flatMap/andThen (chain fallible steps, flattening nested Results). The first err short-circuits the rest, propagating to the end with no try/catch.

Frequently asked questions

Is the “Railway-Oriented Programming” lesson free?

Yes — the full text of “Railway-Oriented Programming” 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 “Railway-Oriented Programming”?

Chain operations that may fail without try/catch. 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 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Railway-Oriented Programming” 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