tracks / javascript-node-to-typescript
JavaScript/Node
TypeScript

A guided path for JavaScript and Node developers learning TypeScript.

Turn familiar JavaScript runtime code into safer, better-specified systems.

This track is for JavaScript and Node developers who already know the runtime and want safer refactors, clearer contracts, and better tooling through TypeScript. It focuses on annotations and inference, safer API shapes, boundary typing, typed tests, and practical migration strategy.

6 lessons~2.5 hrscomparison-firststatus: stableupdated Apr 2026

before you start

  • $You already write real JavaScript/Node code. This path assumes professional instincts, not beginner-level programming lessons.
  • $Expect comparison-first modules: each stop starts from familiar JavaScript/Node habits, then shows where TypeScript agrees or pushes back.
  • $Plan to practice the target ecosystem directly — syntax, testing, and design choices should feel native by the end, not translated.

by the end you can

  • Read and write idiomatic TypeScript without translating every line back through JavaScript/Node.
  • Spot which JavaScript/Node instincts transfer cleanly and which ones need a different TypeScript mental model.
  • Use the six modules as a working checklist when you build your first real TypeScript tool, service, or feature.

syllabus

6 modules, one capstone.

6 lessons · ~2.5 hrs
module 01
1 lesson · ~25 min

Mindset shift

Reframe TypeScript as a way to describe and defend contracts in code that still runs as ordinary JavaScript.

module 02
1 lesson · ~25 min

Annotations and inference

Learn where TypeScript annotations help, where inference is already enough, and how generics and module surfaces sharpen existing JavaScript code.

module 03
1 lesson · ~25 min

Safer API shapes

Move from loose JavaScript objects toward explicit TypeScript models for handlers, payloads, and API results.

module 04
1 lesson · ~25 min

Boundary typing

Learn how TypeScript sharpens JavaScript error and input handling by forcing clearer assumptions at the edges.

module 05
1 lesson · ~25 min

Typed tests and mocks

Use TypeScript in tests to keep fixtures, mocks, and helper APIs honest without turning the suite into a type exercise.

module 06
1 lesson · ~25 min

Migration strategy

Adopt TypeScript incrementally in real JavaScript/Node codebases by typing boundaries and public APIs before chasing total coverage.

track reference

Keep the shared translation aids in one place.

These are track-wide lookup tables and task patterns, not lesson-specific reading. Use them when you need a quick reset on the recurring source-to-target language translations.

Data type mappings

Recheck the building blocks when a translation starts to wobble.

JavaScript/Node

string

TypeScript

string

Common operations

  • Template literals and string helpers remain familiar.
  • Type annotations matter most at function and module boundaries, not on every local string.
  • Keep runtime validation separate from the compile-time type.

JavaScript/Node

array

TypeScript

array / T[]

Common operations

  • Push and array pipelines remain familiar.
  • Element types become explicit when the array crosses a public boundary.
  • Use readonly arrays or generics when the contract needs to signal more than ordinary JS arrays do.

JavaScript/Node

object / null / undefined

TypeScript

typed object shape / union / null

Common operations

  • Use interfaces or type aliases for real contracts.
  • Model missing values and variants with unions instead of loose optional-field objects.
  • Keep unknown at boundaries until data is proven safe.

Comparative cheat sheet

Keep the most common tasks visible while you practice.

TaskJavaScript/NodeTypeScript
Define a public function contractfunction greet(name) { return `hello ${name}`; }function greet(name: string): string { return `hello ${name}`; }
Type an object boundaryfunction loadUser(user) { return user.name; }type User = { name: string }; function loadUser(user: User): string { return user.name; }
Handle unknown input safelyfunction readName(body) { return body.name.trim(); }function readName(body: unknown): string { if (typeof body !== 'object' || body === null || !("name" in body) || typeof body.name !== 'string') { throw new Error('invalid name'); } return body.name.trim(); }
Model missing values honestlyif (!user) { return null; }if (user === null) { return null; }
Type a test helperconst makeUser = (overrides = {}) => ({ id: '1', name: 'Ana', ...overrides });type User = { id: string; name: string }; const makeUser = (overrides: Partial<User> = {}): User => ({ id: '1', name: 'Ana', ...overrides });

capstone

Ship a small TypeScript project that proves the mental model stuck.

Build one focused artifact in TypeScript using the same comparison-first habits from the track: start from a familiar JavaScript/Node shape, then deliberately redesign it the way TypeScript expects.

  • Translate a familiar JavaScript/Node data flow into idiomatic TypeScript structure instead of preserving the old shape by force.
  • Apply the early modules to data modeling, control flow, and API boundaries before you add tooling, polish, or deployment concerns.
  • Use the later modules to verify, test, and package the result the way TypeScript developers expect to see it shipped.

ready?

Start with module 01 — Mindset shift.

Begin