~/VibeHandbook
$39

Languages

typescriptlang.org

TypeScript

What it is

Think of a spell-checker that underlines a misspelled word as you type, before you ever hit send. TypeScript does that for your code. It is JavaScript with a static type system layered on top — a set of rules that checks your code as you write it and flags mistakes early. It compiles down to plain JavaScript, so it runs anywhere JS runs — browsers, Node, Deno, Bun, runtimes — while catching a whole class of bugs before your code ever executes.

Strengths

  • Static types catch typos, null mistakes, and shape mismatches at compile time.
  • Outstanding editor experience: autocomplete, inline docs, safe refactors.
  • Gradual adoption — you can type as much or as little as you want.
  • The same language across and , with a huge npm (Node Manager) ecosystem.

Trade-offs

  • A build/compile step and tsconfig.json to configure.
  • The type system is powerful enough to get genuinely complex (generics, conditional types) and can become a time sink.
  • The type checks only happen while you write and build the code. Once the program is actually running, those checks are gone, so you still need runtime validation (a second check that inspects real data as the program runs, e.g., Zod) for untrusted input.
  • Setup and tooling churn across bundlers and runtimes.

When to reach for it

Reach for TypeScript on any non-trivial JavaScript project, especially with multiple contributors or a long lifespan. It is the default for modern web apps (React, Next.js, SvelteKit), Node/edge backends, and anything where refactoring safety matters.

Vibe coding fit

AI assistants thrive in TypeScript because the type checker gives them — and you — a fast feedback loop: paste a compile error back and the model usually fixes it cleanly. Direct the AI by asking for precise types instead of any, and request runtime validation at trust boundaries ( (Application Programming Interface) inputs, environment variables (env vars)). Tell it your runtime and versions explicitly so generated imports and config match. When types get hairy, ask the model to explain the inferred type rather than blindly widening it.

type User = { id: number; name: string; email?: string };

function greet(user: User): string {
  return `Hi ${user.name}` + (user.email ? ` <${user.email}>` : "");
}

console.log(greet({ id: 1, name: "Ada" }));