~/langs $ bunx tsc --strict // 0 errors (at compile time, anyway)

CTYPESCRIPT

the illusionist · a great type system on a cursed lineage

2012 born at Microsoft 10 days: the runtime's design budget 0 types left at runtime 1 runtime in every pocket

[01] ORIGIN

JavaScript was designed in ten days in 1995. TypeScript is twelve years of Microsoft's best compiler people apologizing for that, brilliantly.

Anders Hejlsberg (Turbo Pascal, Delphi, C#) shipped TypeScript in 2012 with a thesis nobody believed at the time: you can bolt a sound-enough, gradual, structural type system onto JavaScript without changing the runtime, and the entire industry will adopt it. The entire industry adopted it. The types exist only at compile time, the runtime stays the ten-day language underneath, and the gap between those two facts is where both the magic and the lies live. This site is TypeScript on Bun; the language is not the problem. The world around it is.

creatorAnders Hejlsberg, Microsoft, 2012
paradigmgradually-typed JavaScript; the types are advice
memoryGC'd, far away, not your concern (that's the problem)
depsnpm: a supply-chain attack with a registry attached
famous userseveryone with a frontend, which is everyone
my usethis very site: one Bun.serve() call, zero config

[02] WHAT IT GETS RIGHT

ult narrowing

Discriminated unions plus control-flow analysis: check the tag and the compiler reshapes the type in your hands, branch by branch. The best everyday type UX in the industry, in any language, and it isn't close.

stance structural typing

Shape matters, not lineage. If it has the fields, it fits the type: the way data actually behaves at a protocol boundary, formalized instead of fought with class hierarchies.

passive the inference engine

Write the code; the compiler works out the types and the hover tooltip knows more about your data than you do. Annotations only where they earn their keep.

aura infinite range

The only runtime sitting in every browser tab and pocket on earth. When the deliverable is "runs on whatever the user has", there is no second option, so it's good that the type system is this nice.

stance gradual adoption

Rename one .js file at a time and tighten as you go. Types arrive without a rewrite, which is the only reason any large JavaScript codebase ever got them at all.

buff bun

One fast tool where node + npm + webpack + jest used to be. This site is one Bun.serve() call serving HTML that imports TypeScript directly. The toolchain pain is optional now; most people just haven't noticed yet.

[03] THE CODE

type NostrEvent =
  | { kind: "note"; content: string }
  | { kind: "zap";  sats: number }
  | { kind: "dm";   ciphertext: string };

function handle(e: NostrEvent) {
  switch (e.kind) {
    case "note": return render(e.content);    // e is the note arm
    case "zap":  return thank(e.sats);        // e is the zap arm
    case "dm":   return decrypt(e.ciphertext); // e is the dm arm
  }
  // add a kind tomorrow and strict mode flags every
  // switch that forgot about it. that part is great.
}

The illusion at its best: the compiler walks the branches with you and the types narrow like a good argument. Just remember it's all erased at runtime; one as any from a dependency and the whole spell breaks silently.

[04] THE BAD

// status effects

  • NODE_MODULES GRAVITY WELLthe dependency tree has the mass of a small moon and its own weather. The rap sheet is mostly an npm rap sheet, and that is not a coincidence.
  • COSTUME BREAKS AT RUNTIMEthe types are an illusion the compiler maintains for your benefit; at runtime it is all JavaScript, and any is one keystroke of surrender away. Validation at the boundary is on you.
  • FRAMEWORK CHURNthe framework of the week has a half-life of eighteen months, and the migration guide assumes you already migrated.
  • TYPE GOLFthe type system is Turing complete and some of your coworkers know it. Conditional mapped template-literal types can model anything, including problems you didn't have.
  • THE FLOOR IS STILL JS0.1 + 0.2, ==, this, date handling: the ten-day foundation leaks through every abstraction built on it. The illusionist is brilliant; the stage is cursed.

[05] VERDICT

C tier, and the C is for "circumstances". Best-in-class types, held hostage by the world they live in.

Use it for everything that must run in a browser, which is the one arena where it has no rival; use Bun and skip the toolchain tax, like this site does. Keep the dependency tree shallow and vendored, validate at the boundaries, and it's genuinely pleasant. Just don't mistake the costume for armor: when the work is a server you own, Odin is faster, simpler and honest about memory; when it holds keys, Rust.

// the type system deserves a better runtime. it knows. you can tell it knows.