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
- The Problem with Throwing Errors
- Modeling Result Types
- Option and Maybe Types
- Railway-Oriented Programming