ESC

Type to search the knowledge base.

TypeScript for JavaScript Engineers

A practical on-ramp: what TS adds to JS, strict mode basics, gradual migration, and the frontend patterns that matter first.

beginner3 min read
  • typescript
  • typescript-for

If you already write modern JavaScript, TypeScript is not a new language so much as JavaScript plus a type layer that erases at compile time. The runtime is still JS. The win is earlier feedback: wrong props, bad API shapes, and null access fail in the editor instead of in production.

Docs: TS for JS Programmers, Handbook.

What changes day one

// JS
function greet(name) {
  return 'Hello ' + name.toUpperCase();
}

// TS
function greet(name: string) {
  return 'Hello ' + name.toUpperCase();
}

greet(42); // compile error

Syntax you already know stays: async/await, modules, classes, destructuring. You add annotations, interfaces/types, and generics as needed.

Mental model

  1. Types describe values — they don’t exist at runtime.
  2. Inference is default — annotate boundaries (exports, params) more than every local.
  3. unknown > any at trust boundaries.
  4. Strict mode is the point; loose TS teaches bad habits.
const n = 1 + 2; // inferred number
const el = document.getElementById('app'); // HTMLElement | null

Tooling picture

.ts / .tsx  →  typecheck (tsc)  →  emit or bundler transform  →  JS in browser

With Vite/Next, the bundler strips types; tsc --noEmit (or vue-tsc, etc.) typechecks in CI. Both matter.

Gradual migration

  1. allowJs + rename files file-by-file to .ts/.tsx.
  2. Enable strict on new code; migrate old modules with // @ts-expect-error tickets.
  3. Type public APIs first (shared utils, API clients, design-system props).
  4. Add schema validation for JSON — types alone don’t protect fetch.
// Start
export function formatPrice(cents: number): string {
  return `$${(cents / 100).toFixed(2)}`;
}

Frontend-first topics (priority order)

Topic Why
Primitives + object types Props and state
Unions + narrowing UI state machines
unknown vs any API/JSON safety
Generics basics Lists, hooks, utils
Utility types Forms and DTOs
React prop/event types Daily UI work

Deep links: basic types, unknown vs any, narrowing, typing React props.

Common JS → TS confusions

Optional chaining already exists in JS — TS adds checking that you handled null:

user?.address?.city;

Default params work the same; types should match.

Destructuring needs types on the whole object:

function Button({ label, onClick }: { label: string; onClick: () => void }) {
  return (
    <button type="button" onClick={onClick}>
      {label}
    </button>
  );
}

JSON.parse returns any historically — type as unknown and validate.

Don’t boil the ocean

Skip early: complex conditional types, heavy declaration merging, inventing a mini type language for one component. Ship typed props and strict null checks first.

Interview out-loud answer

“TypeScript is typed JavaScript that erases at compile time. I annotate boundaries, lean on inference, use strict null checks, prefer unknown at I/O, and migrate incrementally with CI typecheck. Types don’t replace runtime validation for untrusted data.”

Learning path (two weeks)

Days 1–3: primitives, unions, narrowing, strict null. Days 4–6: props, events, generics basics. Days 7–10: utility types, unknown at boundaries, small schema validation. Avoid advanced conditional types until those are comfortable in real PRs.

Further reading

Related guides