You've typed arr.length a thousand times at runtime. At the type level it's the first puzzle every utility library opens with. Hand the compiler 123 and ask: how long is it?

Seven puzzles sit dark on the workbench. This is the first — the one that teaches your code HOW LONG a tuple is, without running any of it. The job sounds trivial: “`[1, 2, 3]` has three elements.” You know it; the compiler knows it; somewhere between your brain and your codebase the knowledge gets lost. Your form library wants form[0].name to be the literal "email", not the widened string. Your router wants '/users/$id' parsed into { id: string }, not Record<string, unknown>. Every one of those pipelines starts with the same primitive: reading a single VALUE off a tuple TYPE. Length is the warm-up — four lines of prose, one line of code, one panel green. Six puzzles after it.

Attempt 1 — the stale definitionWall
FIG. 1 — RECIPE EDITOR
1
// Attempt 1 — the stale definition. It compiles.
2
// It also throws away every literal the caller knew.
3
type Length<T extends readonly unknown[]> = number
4
5
type L = Length<[1, 2, 3]>
6
//   ^? number   ← the shape is right. The TRUTH is gone.
— The recipe — one line by the end of this puzzle —
FIG. 2 — EVALUATOR
input123
expected3
actualnumberfail
FIG. 3 — TEST SUITE · 4 CASES
123 3pending
[] 0pending
readonly ['a', 'b'] 2pending
[string, number, boolean] 3pending
— Flip all four green to clear this puzzle —
Progress
WallRevealCapstone

You reach for T.length. That's value-level — it errors. typeof T.length — also value-level, also errors. You're writing a type, not running code.

The workbench above has four panels. The top is a recipe editor — it'll rewrite itself, one line at a time, as you work through three checkpoints. Below that, an evaluator shows what the CURRENT recipe produces when handed 123 — the canonical three-element tuple. Then the four-fixture test suite that'll go from pending to pass as the recipe lands. Then three beads showing which checkpoints you've cleared. Read the recipe pane. It's the naive first attempt — a one-line alias that compiles cleanly and achieves NOTHING. The answer it gives is technically right and practically useless.

Read the recipe carefully. type Length<T extends readonly unknown[]> = number takes a tuple on the left and returns the constant number on the right. If we apply it to 123, what type does the compiler report for L?