Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions typescript-book/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[book]
title = "Rust for TypeScript Programmers"
description = "A comprehensive guide to learning Rust for developers with TypeScript experience"
authors = ["Microsoft"]
language = "en"

[preprocessor.mermaid]
command = "mdbook-mermaid"

[output.html]
git-repository-url = "https://github.com/microsoft/RustTraining"
49 changes: 49 additions & 0 deletions typescript-book/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Summary

[Introduction](ch00-introduction.md)

---

# Part I — Foundations

- [1. Introduction and Motivation](ch01-introduction-and-motivation.md)
- [2. Getting Started](ch02-getting-started.md)
- [3. Built-in Types](ch03-built-in-types.md)
- [4. Control Flow](ch04-control-flow.md)
- [5. Data Structures and Collections](ch05-data-structures-and-collections.md)
- [6. Enums and Pattern Matching](ch06-enums-and-pattern-matching.md)

---

# Part II — Core Concepts

- [7. Ownership and Borrowing](ch07-ownership-and-borrowing.md)
- [Lifetimes for TypeScript Developers](ch07-1-lifetimes.md)
- [8. Crates and Modules](ch08-crates-and-modules.md)
- [Testing Patterns](ch08-1-testing-patterns.md)
- [9. Error Handling](ch09-error-handling.md)
- [Error Handling Best Practices](ch09-1-error-handling-best-practices.md)
- [10. Traits and Generics](ch10-traits-and-generics.md)
- [Generics Deep Dive](ch10-1-generics-deep-dive.md)
- [11. From and Into Traits](ch11-from-and-into-traits.md)
- [12. Closures and Iterators](ch12-closures-and-iterators.md)

---

# Part III — Advanced Topics & Migration

- [13. Concurrency](ch13-concurrency.md)
- [Async/Await — From Promises to Futures](ch13-1-async-await.md)
- [14. Unsafe Rust and FFI](ch14-unsafe-rust-and-ffi.md)
- [WebAssembly and wasm-bindgen](ch14-1-webassembly.md)
- [15. Migration Patterns](ch15-migration-patterns.md)
- [16. Best Practices](ch16-best-practices.md)
- [Avoiding Excessive clone()](ch16-1-avoiding-excessive-clone.md)
- [Logging and Tracing Ecosystem](ch16-2-logging-and-tracing-ecosystem.md)
- [17. TypeScript → Rust Semantic Deep Dives](ch17-ts-rust-semantic-deep-dives.md)

---

# Part IV — Capstone

- [18. Capstone Project: REST API Server](ch18-capstone-project.md)
77 changes: 77 additions & 0 deletions typescript-book/src/ch00-introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Rust for TypeScript Programmers: Complete Training Guide

A comprehensive guide to learning Rust for developers with TypeScript experience. This guide
covers everything from basic syntax to advanced patterns, focusing on the conceptual shifts
required when moving from a dynamically-typed runtime with a garbage collector and an optional
type system to a statically-typed systems language with compile-time memory safety.

## How to Use This Book

**Self-study format**: Work through Part I (ch 1–6) first — these map closely to TypeScript
concepts you already know and will feel familiar. Part II (ch 7–12) introduces the ideas that
make Rust *different*: ownership, borrowing, lifetimes, and traits. These are where TypeScript
developers typically need the most time, so take it slow. Part III (ch 13–17) covers advanced
topics, migration strategies, and the async runtime model. Part IV wraps up with a capstone
project that ties everything together.

**Workshop format (3 days)**:

| Day | Chapters | Theme |
|-----|----------|-------|
| 1 | 1 – 6 | Foundations: types, data, control flow |
| 2 | 7 – 12 | Core: ownership, traits, generics, iterators |
| 3 | 13 – 18 | Advanced: async, Wasm, migration, capstone |

**Quick reference**: Each chapter starts with a "TypeScript ↔ Rust" comparison table so you can
scan for equivalents fast. Side-by-side code blocks are used throughout to build on your
existing TypeScript knowledge.

## What You Already Know (and How It Helps)

Coming from TypeScript, you already have a strong foundation:

- **Static types** — You understand type annotations, generics, union types, and structural
typing. Rust's type system will feel both familiar and stricter.
- **Algebraic data types** — TypeScript's discriminated unions (`type Shape = Circle | Square`)
are conceptually close to Rust enums.
- **Generics** — You're used to `Array<T>`, `Promise<T>`, and generic functions. Rust generics
work similarly but are monomorphized at compile time.
- **Async/await** — TypeScript's `async`/`await` over Promises maps to Rust's `async`/`await`
over Futures, though the execution model is very different.
- **Module systems** — TypeScript's ES module imports/exports have clear parallels to Rust's
`mod`, `use`, and `pub`.
- **Toolchain** — If you're comfortable with `npm`, `tsc`, `eslint`, and `prettier`, you'll
find `cargo`, `rustc`, `clippy`, and `rustfmt` refreshingly similar in purpose.

## What Will Be New

These are the concepts without direct TypeScript equivalents:

- **Ownership and borrowing** — No garbage collector. The compiler enforces memory safety rules
at compile time.
- **Lifetimes** — Explicit annotations that tell the compiler how long references live.
- **Move semantics** — Assigning a value can *move* it, making the original binding invalid.
- **No null, no undefined** — `Option<T>` and `Result<T, E>` replace nullable types.
- **No classes** — Structs + traits replace class-based OOP.
- **No runtime reflection** — No `typeof` at runtime, no `Object.keys()` on arbitrary types.
- **Manual string handling** — Multiple string types (`String`, `&str`, `OsString`, …) instead
of one universal `string`.
- **No exceptions** — Errors are values, not thrown. `?` replaces `try/catch` in most cases.

## Conventions

Throughout this book:

- 🟦 **TypeScript** code blocks show the familiar pattern.
- 🦀 **Rust** code blocks show the idiomatic Rust equivalent.
- 💡 **Key insight** callouts explain the conceptual shift.
- ⚠️ **Common pitfall** callouts warn about traps TypeScript developers commonly fall into.
- 🏋️ **Exercise** callouts provide hands-on practice.

## Prerequisites

- Comfortable writing TypeScript (basic generics, async/await, union types).
- A working Rust installation: [rustup.rs](https://rustup.rs).
- An editor with `rust-analyzer` (VS Code recommended — you likely already have it).

Let's get started!
98 changes: 98 additions & 0 deletions typescript-book/src/ch01-introduction-and-motivation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Introduction and Motivation

## Why Rust for TypeScript Developers?

As a TypeScript developer, you chose TypeScript over JavaScript for a reason: you value type
safety, better tooling, and catching bugs early. Rust takes that philosophy to its logical
extreme — every category of bug that TypeScript's type system can't catch (null pointer
dereferences at runtime, data races, use-after-free) is caught at compile time in Rust.

### Where TypeScript Falls Short

TypeScript improves on JavaScript, but it still inherits fundamental limitations:

- **Runtime overhead** — V8 (or Deno/Bun) adds GC pauses, JIT warm-up, and memory overhead.
- **Type erasure** — Types vanish at runtime. A `User` type offers zero runtime guarantees.
- **`any` escape hatch** — One `any` can silently break an entire type chain.
- **Concurrency model** — Single-threaded event loop. True parallelism requires worker threads
with message passing and serialization overhead.
- **No memory control** — You cannot control allocations, layout, or lifetimes.

### What Rust Offers

| Concern | TypeScript | Rust |
|---------|-----------|------|
| Null safety | Optional (`strictNullChecks`) | Enforced (`Option<T>`) |
| Error handling | Thrown exceptions (unchecked) | `Result<T, E>` (checked) |
| Memory management | Garbage collector | Ownership system (zero-cost) |
| Concurrency | Single-threaded + workers | Fearless concurrency (threads, async) |
| Performance | JIT-compiled, GC pauses | Compiled to native, no runtime |
| Type guarantees | Erased at runtime | Present at compile time, monomorphized |
| Package manager | npm / yarn / pnpm | cargo (built-in) |

### When to Reach for Rust

Rust is not a replacement for TypeScript in every scenario. Use Rust when you need:

- **Performance-critical services** — HTTP servers, data pipelines, real-time systems.
- **WebAssembly modules** — Ship compiled Rust to the browser alongside your TypeScript app.
- **CLI tools** — Fast startup, single binary, no runtime dependency.
- **Embedded / systems** — Where a GC and runtime are not available.
- **Correctness guarantees** — When "it compiled, therefore it works" matters.

Keep using TypeScript for rapid UI prototyping, full-stack web apps where developer velocity
is paramount, and anywhere the Node.js ecosystem gives you a critical advantage.

## Toolchain Comparison

If you're used to the TypeScript toolchain, here's how Rust's tools map:

| TypeScript | Rust | Purpose |
|-----------|------|---------|
| `npm` / `yarn` / `pnpm` | `cargo` | Package management and task runner |
| `package.json` | `Cargo.toml` | Project manifest |
| `node_modules/` | `~/.cargo/registry/` | Dependency cache |
| `tsc` | `rustc` | Compiler |
| `tsconfig.json` | `Cargo.toml` + `rustfmt.toml` | Compiler and formatter config |
| `eslint` | `clippy` | Linter |
| `prettier` | `rustfmt` | Formatter |
| `jest` / `vitest` | `cargo test` | Test runner (built-in) |
| `tsx` / `ts-node` | `cargo run` | Run a project |
| `npmjs.com` | `crates.io` | Package registry |
| `tsdoc` / `typedoc` | `cargo doc` / `rustdoc` | Documentation generator |

## Hello, Rust!

Let's compare a minimal program:

🟦 **TypeScript**
```typescript
function greet(name: string): string {
return `Hello, ${name}!`;
}

console.log(greet("TypeScript"));
```

🦀 **Rust**
```rust
fn greet(name: &str) -> String {
format!("Hello, {name}!")
}

fn main() {
println!("{}", greet("Rust"));
}
```

💡 **Key differences to notice**:
- `fn` instead of `function`.
- Return type comes after `->`, not before with `:`.
- No `return` keyword needed — the last expression is the return value (no semicolon).
- `&str` is a *borrowed* string slice; `String` is an *owned* heap string. We'll cover this
distinction in depth in Chapter 7.
- `main()` is the entry point — there's no top-level execution like Node.js.
- `println!` is a *macro* (note the `!`), not a function.

🏋️ **Exercise**: Create a new project with `cargo new hello-ts` and modify `src/main.rs` to
print a greeting. Run it with `cargo run`.
114 changes: 114 additions & 0 deletions typescript-book/src/ch02-getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Getting Started

## Installing Rust

```bash
# Install rustup (manages Rust toolchains)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Verify installation
rustc --version
cargo --version
```

This is analogous to installing Node.js via `nvm` — `rustup` manages compiler versions the way
`nvm` manages Node versions.

## Creating a Project

🟦 **TypeScript**
```bash
mkdir my-project && cd my-project
npm init -y
# edit package.json, install typescript, create tsconfig.json…
```

🦀 **Rust**
```bash
cargo new my-project
cd my-project
# That's it. Cargo.toml and src/main.rs are ready.
```

`cargo new` creates:

```
my-project/
├── Cargo.toml # ≈ package.json
└── src/
└── main.rs # entry point
```

### Cargo.toml vs package.json

```toml
[package]
name = "my-project"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
```

Compared to `package.json`, there are no `devDependencies` vs `dependencies` split for the
binary itself — `[dev-dependencies]` exists but is only for test/build-time crates.

## Cargo Commands You'll Use Daily

| Command | Purpose | TypeScript equivalent |
|---------|---------|----------------------|
| `cargo build` | Compile (debug) | `tsc` |
| `cargo build --release` | Compile (optimized) | `tsc` + bundler |
| `cargo run` | Build + run | `tsx src/index.ts` |
| `cargo test` | Run all tests | `vitest run` |
| `cargo clippy` | Lint | `eslint .` |
| `cargo fmt` | Format | `prettier --write .` |
| `cargo doc --open` | Generate and view docs | `typedoc` |
| `cargo add serde` | Add a dependency | `npm install serde` |

## Editor Setup

If you use VS Code (most TypeScript developers do):

1. Install the **rust-analyzer** extension (replaces the older Rust extension).
2. Install **CodeLLDB** for debugging.
3. Optional: **Even Better TOML** for `Cargo.toml` syntax highlighting.

`rust-analyzer` provides the same kind of experience you get from TypeScript's language
server — inline type hints, go-to-definition, auto-imports, and real-time error checking.

## Your First Cargo Project

```rust
// src/main.rs
fn main() {
let language = "Rust"; // type inferred as &str
let year: u32 = 2015; // explicit type annotation
println!("{language} was released in {year}");
}
```

Run it:
```bash
$ cargo run
Compiling my-project v0.1.0
Finished dev [unoptimized + debuginfo] target(s)
Running `target/debug/my-project`
Rust was released in 2015
```

💡 **Key insight**: `let` in Rust is *immutable by default*. To mutate a variable, use
`let mut`. This is the opposite of TypeScript, where `let` is mutable and `const` is
immutable.

```rust
let x = 5;
// x = 6; // ❌ error: cannot assign twice to immutable variable
let mut y = 5;
y = 6; // ✅ ok
```

🏋️ **Exercise**: Create a project with `cargo new playground`, add the `chrono` crate with
`cargo add chrono`, and print today's date.
Loading