typeover
curriculum
TS

ZIG

Curriculum

four modules. Start anywhere — the recommended path is in order, but every theme is browsable. Themes without exercises yet are visible so you can see what's coming.

Progress saves per exercise — re-open any one to continue where you left off. Nothing leaves your browser.

4 modules complete · 0 partial · 0 scaffolded 20/20 themes authored (100%) 180 exercises
the wedge
variables.tsTS
let count: number = 5;
const PI = 3.14;

function double(n: number): number {
  return n * 2;
}
variables.zigZIG
var count: i32 = 5;
const PI: f64 = 3.14;

fn double(n: i32) i32 {
    return n * 2;
}
Same intent, two syntaxes. typeover's whole shape is teaching the second one by leaning on what you already know about the first.

1. Basics

8 themes · 72 exercises

The "you already know this, just spelled differently" module for Zig. Imports, entry points, variables, control flow, functions, the string-is-a-slice convention, and optionals. By the end, you trust that typeover's translation pattern works for Zig too, and writing a hello-world Zig program feels familiar.

Two reflexes Zig wants you to internalise on day one. - Imports use a builtin, not a keyword. const std = @import("std"); binds the standard library to a name. There's no…

9 ready begin →

Zig defaults the other way from TypeScript. const is the default reflex; var is the explicit opt-in when you need to reassign. Type annotations come AFTER the name (`var x: i32…

9 ready begin →

Zig's if looks like TypeScript's: parens around the condition, optional braces around the body. The catch: Zig has no truthy values — the condition must be bool. switch is an…

9 ready begin →

Zig has while (cond) { ... } for condition-driven loops and for (slice) |item| { ... } for iteration. The C-style three-clause for (init; cond; step) is gone — its replacemen…

9 ready begin →

Zig functions look like TS with the type annotations shifted: fn name(param: Type) ReturnType { ... }. Visibility is opt-in via pub fn — top-level functions are private by defa…

9 ready begin →

TypeScript has one numeric type — number — that swallows everything from booleans to billions. Zig is the opposite: every integer width is explicit (i8, i16, i32, i64, `u…

9 ready begin →

There's no String type in Zig. String literals are byte slices typed as []const u8 — same shape as any other slice of read-only bytes. Length comes from .len (a usize), ind…

9 ready begin →

TypeScript uses T | null (or T | undefined) to mark "maybe absent" values; Zig's analogue is the type prefix ?T. A ?T value is either some T or null. Three idiomatic wa…

9 ready begin →

2. Types

4 themes · 36 exercises

Zig's type vocabulary is similar enough to TypeScript that you can lean on the analogues — struct matches object literals, enum matches string literal unions, union(enum) matches discriminated unions. The diverging bits are pointers (*T, *const T, [*]T, ?*T — each meaning something specific) and arrays vs slices ([N]T length-in-type vs []T slice). Lays the type foundation that Memory + Errors + Comptime build on.

Zig structs are TypeScript object literals' closest cousin: const Point = struct { x: i32, y: i32 };. Instantiation uses dot-prefixed field initializers (`Point{ .x = 3, .y = 4 }…

9 ready begin →

TypeScript reaches for string-literal unions ("red" | "green" | "blue") for enums and discriminated unions ({ kind: "circle", radius: 5 } | { kind: "square", side: 3 }) for sum…

9 ready begin →

TypeScript has no pointer syntax — everything is a reference under the hood. Zig has dedicated syntax for pointers, and several flavours: *T (single pointer to one T), *const T

9 ready begin →

Zig has two collection shapes where TypeScript has one. [N]T is a fixed-length array; the length N is part of the type, known at compile time. []T is a slice: a pointer plus a runt…

9 ready begin →

3. Memory

4 themes · 36 exercises

The friction module. Allocators are explicit: every dynamic allocation goes through one, and you pick which. defer is the structural tool that makes manual memory safe to write (and read). Ownership is enforced by convention, not the compiler — "whoever calls init calls deinit." Once comfortable here, the rest of the Zig stdlib reads naturally.

Zig has no hidden allocations. Every dynamic alloc goes through an Allocator interface value, and you pick which. The three you meet first: page_allocator (OS page granularity, sim…

9 ready begin →

defer is Zig's structural cleanup tool: each defer statement runs when the enclosing block exits, in LIFO order. errdefer is the same idea, but it only fires when the function retu…

9 ready begin →

ArrayList(T) is Zig's growable slice — your TypeScript Array equivalent. In Zig 0.16 it's an unmanaged container by API convention: you initialize with the .empty literal, pass the…

9 ready begin →

Zig has no borrow checker — ownership is convention, not enforcement. The rule that makes manual memory livable: whoever calls init is responsible for calling deinit. A function th…

9 ready begin →

4. Errors

4 themes · 36 exercises

Zig errors are first-class values from a finite set declared per-API. error{ Empty, BadInput } declares a set; !T is the error-union return type. try is sugar for "propagate-on-error, unwrap-on-success." catch handles. There's no exception hierarchy, no try/catch ladder, no fall-through — every error case is named, every callsite is explicit. Builds on Module 3: errdefer finally makes sense in its native habitat.

An error set is a finite enumeration of named errors — declared as error{ Empty, BadDigit, ... }. Different APIs declare their own sets; the compiler tracks which errors a function…

9 ready begin →

There are three ways to consume an error union. try expr is the propagator: on error, return the error to the caller; on success, unwrap the value. expr catch <default> substitutes…

9 ready begin →

A function that can fail declares a return type with a leading bang: !T means "either a T or an error." The error set is usually INFERRED from the function body — every return erro…

9 ready begin →

Errors are for conditions the caller should be expected to handle (bad input, out of memory, missing file). Panics are for conditions that indicate a programmer bug — invariants th…

9 ready begin →

typeover · curriculum · pass 2

← back to home