Skip to content

Rust with TypeScript

If you know TypeScript, Rust is closer than you think.
TypeScript
// Errors are absent from types
async function getUser(id: string) {
const res = await fetch(`/api/users/${id}`);
const user = await res.json(); // inferred as `any`
return user.name.toUpperCase(); // may crash at runtime
}
Rust
// Errors are explicit in the type signature
async fn get_user(id: &str) -> Result<String, Error> {
let user: User = fetch_user(id).await?; // validated at compile time
Ok(user.name.to_uppercase()) // None case caught at compile time
}


Ch.1 — Introduction

TypeScript is already good enough — so why Rust? Runtime errors, performance ceilings, GC pauses. Real pain points every TypeScript developer has hit.

Ch.2 — Mental Model

GC vs Ownership, runtime vs compile-time safety, zero-cost abstractions. Before syntax, you need to shift how you think.

Ch.3 — Syntax Basics

Variables, functions, structs, traits, Option, Result, async/await, generics — TypeScript and Rust side by side.

Ch.4 — Ownership & Borrowing

Why the borrow checker says no, stack vs heap, lifetimes. Direct answers to “why does this work in JS but not Rust?”

Ch.5 — Cargo & Modules

From npm and package.json to Cargo.toml. Package manager, module declarations, pub/use — compared to TypeScript import/export.

Ch.6 — Enums & Pattern Matching

TypeScript union types, Rust-style. Why match’s exhaustiveness requirement makes your code safer — shown through a state machine example.

Ch.7 — Collections

Array/Map/String vs Vec/HashMap/String. How ownership interacts with collections, and when to clone vs borrow.

Ch.8 — Iterators & Closures

Why .map().filter().collect() chains compile down to the same assembly as a C for-loop — zero-cost abstractions in action.

Ch.9 — Traits in Depth

dyn Trait, Display, From/Into, trait objects. What TypeScript interfaces can’t do — and how Rust traits fill that gap.

Ch.10 — Smart Pointers

Box, Rc, Arc, RefCell — when to use each, and how they map to familiar JavaScript reference patterns.

Ch.11 — Concurrency

Threads, channels, Mutex, async runtimes. How Rust prevents data races at compile time — something no JS runtime can do.

Ch.14 — Learning Roadmap

A 6-month curriculum, curated resources, and tips for TypeScript developers. How to stop fighting the borrow checker and start working with it.


  1. Shift your mindset (Ch.1–2)

    Philosophy before syntax. Understand why memory is safe without GC, and why compile-time guarantees beat runtime checks.

  2. Learn the core language (Ch.3–5)

    Rust syntax mapped 1:1 to TypeScript concepts, Ownership & Borrowing, and the Cargo module system — in sequence.

  3. Master the type system (Ch.6–9)

    Enums, collections, iterators, traits. After this, you can read and write Rust without getting stuck.

  4. Apply it in practice (Ch.10–14)

    Smart pointers, concurrency, real-world patterns, testing, and a roadmap to guide your self-study.


TypeScriptRust
Type safetyCompile-time (partial)Compile-time (comprehensive)
Null safetyT | null + optional chainingOption<T> + exhaustive match
Error handlingtry/catch (untyped)Result<T, E> (typed, enforced)
MemoryGC (automatic, with pauses)Ownership (zero-cost)
PerformanceNode.js levelC/C++ level
Concurrency safetyChecked at runtimeData races blocked at compile time

Rust often feels like the completed version of what TypeScript was reaching for.