TypeScript Survival Guide

Favorite TypeScript Videos — Curated Learning Path

Videos: 160 | Modules: 8 (00-07)

Source: this page organizes a curated TypeScript video curriculum. The videos are linked from the carousel and course map below.


what this course builds

PLACEHOLDER: Introduction to the TypeScript curriculum — what learners will gain, how the modules are structured, and how to approach the material.

course map

moduletitlevideoscore concepts
00module 00 — foundations001A, 002–007, 027, 030, 101–102, 079–085, 112, 114, 118, 152–157, 022, 053–056, 158–159, 068foundations, setup, compile, watch, tsconfig selection, target, lib, js prerequisite, js internals, bootcamp expanded editions, adoption case, strictness ladder, annotations, arrays, node runtime, express, event loop, study roadmap
01module 01 — fundamentals001B, 020, 029, 040, 098, 024–026, 032types, functions, objects, tuples, why-types motivation
02module 02 — type system009, 019, 097, 037, 041, 042, 043–048, 087, 103, 104–106, 109, 111, 113, 115, 117, 120, 135, 146–151, 033–036, 051, 028type aliases, enums, inference, annotations, any, unknown, never, narrowing, unions, literals, returns, discriminated unions, ts-reset, error tuples, brands, as-const, declaration files, definitely typed, prototypes
03module 03 — advanced types038, 039, 110, 121, 059–062extends, arrays, objects, utility types, satisfies, infer, mapped types, type challenges
04module 04 — functions and generics008, 010, 018, 031, 086, 088, 096, 119, 049–050, 052functions, signatures, callbacks, generics
05module 05 — objects and interfaces012-017, 090–095, 124, 126classes, access modifiers, modules, interfaces, oop foundations
06module 06 — patterns and best practices071, 074–075, 116, 122–123, 127–134, 136–145, 067crash-course survey, config, guards, generics, utility types, promises, zod, runtime validation, schemas, anti-patterns, design patterns, factory patterns, code review, clean-code mistakes, review satire, checklists, jest testing, mocking, vitest, playwright, tdd, coverage
07module 07 — project application011, 021, 069, 072–073, 076–078, 089, 107–108, 125, 057–058, 063–066dom, casting, react scaffold, deploy, jsx, todo app, hangman, hooks, context, typewriter, cart, select, notes, multistep, props typing

narrative batch checklist (for the video team)

each narrative delivery follows this order so course expansion can trace it:

  1. land pages — one dir per number (NNN-slug/index.md), frames under static/_assets/favorite-typescript-videos/NNN-slug/.
  2. keep the footer chain intact — every page (except 001/160 endpoints) ends with exactly one Prev (N-1) and one Next (N+1) footer, slugs matching the on-disk dirs.
  3. run python3 scripts/check-library-numbering.py — must print intact before pushing.
  4. update the course map table above if module membership changed.
  5. name the affected numbers in the PR description — course follow-ups cite them against course.ts module sources.

module 00 — foundations

Narratives: 002 · 080 · 003 · 081 · 004 · 082 · 005 · 083 · 006 · 084 · 007 · 085 · 001A · 079 · 027 · 030 · 101 · 102 · 112 · 114 · 118 · 152 · 153 · 154 · 155 · 156 · 157 · 022 · 053 · 054 · 055 · 056 · 068 · 158 · 159

Module 00 is the on-ramp: environment setup, the compile mental model, and the sandbox habit. No type syntax yet — that starts in module 01.


002 — Introduction & Setup (2pZmKW9-I_k, 6:45)

The Net Ninja playlist opener. Core claim: TypeScript is a superset of JavaScript — everything JavaScript can do, plus extras — compiled down to plain JavaScript because browsers do not read .ts natively.

Three benefits previewed: strict (static) types catch errors early, you can write modern JavaScript (arrow functions, let/const, destructuring) and ship compatible output via compilation (same job as Babel), and TypeScript-only extras (generics, interfaces, tuples) arrive later.

Setup checklist from the lesson: install Node.js (needed for npm), install the compiler globally (npm install -g typescript, verify with tsc --version), use VS Code (built-in TypeScript support), and clone the per-lesson branches of the iamshaunjp/typescript-tutorial repo. The series project is a finance logger (log payments/invoices to a list). Screenshot refs: title card, nodejs.org download page, VS Code interface, repo branches page.

Full narrative: 002 — Introduction & Setup (what TypeScript is, and the toolchain)


080 — What TypeScript Is and What to Install (2pZmKW9-I_k, 6:45)

Expanded edition of the lesson-1 opener, from the bootcamp transcript pass. One slide carries the pitch — superset of JavaScript, strict types, modern-feature compile-down, extras (generics, interfaces, tuples) — then the strict-vs-dynamic contrast: declare a number and it can never become a string, so error-checking happens before the browser runs. Setup with a purpose: Node purely as the npm delivery vehicle for the compiler, VS Code for built-in support, per-lesson GitHub branches, the finance-logger mini project every later lesson extends, and the global npm install -g typescript lesson 2 drives.

Screenshot refs: frame-0001.png (series opener) through frame-0007.png (global install) — slides, repo, finance logger, terminal.

Full narrative: 080 — What TypeScript Is and What to Install (superset, strict types, setup) — the complete lesson with all 7 screenshots, code blocks, and transcript corrections.


003 — Compiling TypeScript (iTZ1-85I77c, ~10:30)

The toolchain lesson. The starter project (index.html, styles.css, empty sandbox.js) becomes sandbox.ts — write TypeScript, compile to JavaScript, and the browser loads only the compiled sandbox.js.

Key commands: tsc sandbox.ts compiles (emits sandbox.js, downleveling const to var for compatibility), and tsc sandbox.ts -w watches and recompiles on every save. Saving the .ts alone changes nothing in the browser until you recompile. Same DOM APIs (querySelectorAll, forEach, console.log) work unchanged — the js-to-ts transition is seamless. Live preview via the VS Code Live Server extension. Next lesson moves on to actual types. Screenshot refs: frames/frame_0001.png (starter repo) through frames/frame_0014.png (watch-mode result).

Full narrative: 003 — Compiling TypeScript (sandbox, tsc, and watch mode)


081 — Compiling TypeScript, Expanded Edition (iTZ1-85I77c, ~10:30)

Expanded edition of the toolchain lesson, from the bootcamp transcript pass. One idea drilled end to end: the browser only reads the .js file, so every .ts change must be compiled — the page links sandbox.js, and even a linked .ts would not run. The emit is older JavaScript on purpose (const downlevels to var); same-named .ts/.js files open together produce a phantom redeclare error (ts2451) to ignore; and tsc sandbox.ts -w ends the lesson by recompiling on every save. Verified quotes on the tsc invocation and the watch flag.

Screenshot refs: frame-0001.png (project open) through frame-0011.png (watched recompile) — template, scratch pair, compile, phantom error, loop, watch.

Full narrative: 081 — Compiling TypeScript (sandbox.ts, downlevel emit, and watch mode) — the complete lesson with all 11 screenshots, code blocks, and transcript corrections.


004 — Type Basics (0DzDqtcxnz0, 7:35)

The strict-types lesson. A variable declared as a string stays a string: values are reassignable, types are not. Covers string, number (one type, no int/float split), and boolean — character = 'luigi' is fine, character = 20 errors. TypeScript infers each type from the initializer (hover shows let character: string); explicit annotation (let character: string) is deferred to a later video.

Function parameters get the first annotation: unannotated (diameter) accepts anything and circ('hello') compiles clean only to log NaN at runtime, while (diameter: number) turns the bad call into a compile-time error under tsc sandbox.ts --watch. Checking happens at author time, before emit. Screenshot refs: VS Code sandbox.ts with the three variables plus the circ arrow function, tsc watch-mode terminal, browser console showing 23.56194490192345 after circ(7.5).

Full narrative: 004 — Type Basics (strict types, inference, and first annotation)


082 — Type Basics, Expanded Edition (0DzDqtcxnz0, ~7:34)

Expanded edition of the strict-types lesson, from the bootcamp transcript pass. Values may change, types may not: character/age/isBlackBelt refuse cross-type reassignment with “not assignable” squigglies while same-type updates pass. Two simplifications — one number type (no int/float split), and inference from the initializer so no annotation is written all lesson (“hover over character, we can see it says, character is a string”). Payoff is the circ demo: untyped diameter compiles "hello" into a runtime NaN; (diameter: number) refuses the call before emit — “I’m not gonna compile.”

Screenshot refs: frame-0001.png (first declaration) through frame-0008.png (clean compile) — variables, squigglies, hover inference, untyped vs typed circ.

Full narrative: 082 — Type Basics (primitives, inference, and typed function params) — the complete lesson with all 8 screenshots, code blocks, and transcript corrections.


005 — Objects & Arrays (157NopQ-chU, 7:36)

Arrays and objects inherit their types from the initializer. let names = ['luigi', 'mario', 'yoshi'] only accepts strings (push('toad') fine, push(3) and names[0] = 3 error); let numbers = [10, 20, 30, 40] only accepts numbers; a mixed initializer like ['ken', 4, 'chun-li', 8, 9] accepts every member type (push('ryu'), push(10), mixed[0] = 3 all fine).

Objects work the same way: let ninja = { name: 'mario', belt: 'black', age: 30 } locks each property type (ninja.age = 40, ninja.name = 'ryu' fine; ninja.age = '30' errors) and forbids brand-new properties — once defined, the shape is fixed, and a full reassignment must keep matching property types. Screenshot refs: 157NopQ-chU_frame_001.png (// arrays setup) through 157NopQ-chU_frame_008.png (full reassignment).

Full narrative: 005 — Objects & Arrays (inferred collection types)


083 — Objects & Arrays, Expanded Edition (157NopQ-chU, ~7:35)

Expanded edition of the collections lesson, from the bootcamp transcript pass. Homogeneous arrays lock element type at birth (push(3) into strings errors, index writes checked too); mixed seeds infer a union ((string|number)[]) with fluid positions inside it; objects freeze shape — same-type updates fine, type swaps refused, brand-new props (skills) rejected, whole-object replacement allowed only with identical structure. “Once we initially declare something like this, it has to have the same structure” — “quite strict… but it’s not a bad thing… it gives you cleaner, more predictable code.”

Screenshot refs: frame-0001.png (names seed) through frame-0008.png (whole-object reassignment) — arrays, pushes, mixed union, ninja shape rules.

Full narrative: 083 — Objects and Arrays (element types, union seeds, frozen shapes) — the complete lesson with all 8 screenshots, code blocks, and transcript corrections.


006 — Explicit Types (__92ek8Xh4o, ~8:40)

Inference needs an initial value; when the value comes later, declare the type up front (let character: string;, let age: number;, let isLoggedIn: boolean;) so future assignments are still checked. Arrays annotate the element (let ninjas: string[] = []) — and initialize to [] if you plan to push, since an uninitialized let ninjas: string[] compiles but throws Cannot read property 'push' of undefined in the browser.

Unions widen what is allowed: (string|number|boolean)[] for arrays (parentheses required before []) and string|number for scalars (let uid: string|number takes '123' or 123, not false). Objects range from loose (: object, which still admits arrays) to shaped ({ name: string, age: number, beltColour: string }, enforcing required properties and rejecting excess ones) — the first taste of structural typing. Screenshot refs: VS Code sandbox.ts explicit declarations and union sections, browser console Uncaught TypeError (uninitialized array) then (3) ["hello", 20, false] after the fix.

Full narrative: 006 — Explicit Types (annotations, arrays, unions, objects)


084 — Explicit Types, Expanded Edition (__92ek8Xh4o, ~8:35)

Expanded edition of the explicit-types lesson, from the bootcamp transcript pass. Annotate up front when the value comes later (let character: string;, let age: number;, let isLoggedIn: boolean;) — the commented-out mismatches stay in the file as documentation. Typed arrays plus the empty-array init rule (an uninitialized let ninjas: string[] compiles but throws Cannot read property 'push' of undefined on the first push); unions with the parentheses-before-brackets rule ((string|number|boolean)[] logging (3) ["hello", 20, false], scalar uid: string|number taking '123' or 123); and objects from loose (: object, which still admits arrays) to shaped (ninjaOne/ninjaTwo) — “we’re just declaring the type it should be in the future.”

Screenshot refs: frame-0001.png (lesson sections stubbed out) through frame-0009.png (full file with both ninja objects).

Full narrative: 084 — Explicit Types (declare now, assign later: annotations, arrays, unions, objects) — the complete lesson with all 9 screenshots, code blocks, and transcript corrections.


007 — Project Structure with tsconfig (Y4IiQY9dNRA, ~6:50)

Single-file compiles stop scaling: split author-time src/ from deploy-time public/, generate tsconfig.json once with tsc --init, and wire "rootDir": "./src" to "outDir": "./public". Compile the project with bare tsc, iterate with tsc -w (re-emits on every save). rootDir maps paths but does not fence inputs — a stray root-level file still compiles (error TS6059) until a top-level "include": ["src"] constrains the project. Screenshot refs: frame-0001 (motivation) through frame-0012 (final tsconfig.json with watch-mode compile messages).

Full narrative: 007 — Project Structure with tsconfig (src, outDir, and watch mode)


085 — Project Structure with tsconfig, Expanded Edition (Y4IiQY9dNRA, ~6:50)

Expanded edition of the workflow lesson, from the bootcamp transcript pass. The flat layout splits into author-time src/ and deploy-time public/; tsc --init generates the commented tsconfig.json (“This is gonna be the output of the JavaScript right here, right now we’re saying we want the output to be ECMAScript specification 5”); \"rootDir\": \"./src\" wired to \"outDir\": \"./public\" so a bare tsc builds the whole project. rootDir maps paths but does not fence inputs — a stray root-level file errors TS6059 until a top-level \"include\": [\"src\"] constrains it (“So now it’s gonna look at this and say, OK, I’m only gonna compile things inside the source folder”). Closes with tsc -w re-emitting on every save.

Screenshot refs: frame-0001.png (motivation) through frame-0007.png (watch-mode recompile) — per-file pain, generated config, rootDir/outDir, TS6059, include fence, watch.

Full narrative: 085 — Project Workflow with tsconfig (src, outDir, include, and watch mode) — the complete lesson with all 7 screenshots, code blocks, and transcript corrections.


001A — Setup, First Program, tsconfig (d56mG7DezGs, Part A of 1:04:28)

Mosh Hamedani opener, module-00 half. Premise: no TypeScript knowledge required, basic JavaScript assumed (variables, arrays, objects, functions, arrows, destructuring); watch in order, take notes, do the exercises. TypeScript is a superset of JavaScript — every .js file is valid .ts — created at Microsoft for large-scale apps. Headline feature is static typing (let age: number = 20; rejects age = 'twenty' at compile time); editors also get completion/refactoring, and future-JS features compile down. Drawbacks stated: a compilation step (browsers do not run .ts), and more discipline than quick scripts need.

Setup: Node.js (for npm), npm i -g typescript then tsc -v, VS Code. First program: new folder, index.ts with console.log('hello-world'), compile with tsc index.ts (emits index.js). Annotate (let age: number = 20) and the bad assignment errors at compile time; default emit targets ES5 (let becomes var) and annotations never reach the output. tsc --init generates tsconfig.json; settings used here: target, module, outDir (dist), rootDir (src), include/exclude, sourceMap, strict (+ noImplicitAny, strictNullChecks), noImplicitReturns, noUnusedLocals/noUnusedParameters. Workflow: set outDir, then bare tsc builds the project. Debugging: enable sourceMap, create launch.json, breakpoint + F5, step with F10. Screenshot refs: videos/d56mG7DezGs/frames/frame-0022.jpg (sole code frame, src/index.ts literal types); frames 1–21 are talking-head shots.

Full narrative: 001 — TypeScript Tutorial for Beginners (part A: setup, first program, tsconfig) — the complete lesson with the code screenshot, module checklists, and transcript corrections.


079 — TypeScript for Beginners, the Full Hour (d56mG7DezGs, ~64:27)

Expanded edition of the Mosh hour, from the bootcamp transcript pass — the one page that spans both halves (module-00 setup plus module-01 type system). Three questions answered by building: install (npm i -g typescript), hello-world compile, tsc --init tsconfig tour (target/lib, outDir/rootDir, strict family), VS Code debugging (launch.json, F5, breakpoints, watch), then the type system in dependency order — any/unknown/never with the noImplicitAny rule (“there’s really no point using TypeScript” without it), arrays/tuples/enums, functions and objects with contracts, unions/intersections/literals with typeof narrowing, and null handling graduating from guards to ?./??. Every strictness flag presented as a named safety net with a demo of the bug it prevents.

Screenshot refs: frame-0005.png (static-vs-dynamic slide) through frame-0063.png (optional chaining) — 12 code frames across the toolchain and type-system halves.

Full narrative: 079 — TypeScript for Beginners, the Full Hour (setup, tsc, tsconfig, and the type system) — the complete lesson with all 12 screenshots, code blocks, and transcript corrections.


027 — Learn JavaScript: Full Course for Beginners (PkZNo7MFNFg, ~3:27:00)

The JavaScript-prerequisite anchor. The course assumes learners already know JavaScript, and this freeCodeCamp course (instructor Bo Karnes) is the canonical standalone path there — no TypeScript syntax at all, just the JS mental models TypeScript later constrains. Opening move: “how exactly do you install JavaScript? Well, for the most part you don’t” — every browser runs it. Four follow-along surfaces in order of increasing structure: any editor plus an HTML file with <script> tags, the freeCodeCamp.org editor, CodePen, and Scrimba (where most of the course was recorded).

Covers seven data types (undefined, null, boolean, string, symbol, number, object), var vs let vs const (var function-scoped, let block-scoped, const never reassigned), declare vs assign vs initialize (console.log as the inspection probe), case sensitivity and camelCase, arithmetic through compound assignment (a += 12), string immutability (bracket notation reads but never writes), and — per the frame captions — chained if/else, for loops, the var/let scope comparison, and destructuring with strict mode.

var myName = "Bo";
myName = 8; // var allows reassignment to a different type — TS will later forbid this
let ourName = "freeCodeCamp";
const pi = 3.14;

Screenshot refs: frames-PkZNo7MFNFg/frame_00001.png (“Running JavaScript” slide), frame_00026.png (multiplying numbers), frame_00076.png (bracket notation), frame_00101.png (reusable functions), frame_00126/00151.png (testSize chained conditionals), frame_00176.png (object properties), frame_00201.png (for loops), frame_00226.png (var vs let scope), frame_00251.png (destructuring + strict mode).

Full narrative: 027 — Learn JavaScript: Full Course for Beginners (the JS prerequisite) — the complete lesson with all 10 screenshots, code blocks, and transcript corrections.


030 — 100+ JavaScript Concepts You Need to Know (lkIFF4maKMU, ~12:23)

The densest prerequisite survey in the set: ~12 minutes from Brendan Eich at Netscape to bundlers, touching every layer the course assumes — runtime, types, scope, functions, prototypes, async, modules, DOM, tooling. Use it as the module 00–04 topic checklist and for one-sentence recall definitions. It names TypeScript explicitly as the static-analysis fix: “you’ve got 99 problems and JavaScript is every single one of them … use TypeScript.”

Beats banked: ECMAScript standard, Node.js/Deno runtimes, lexical scope and var hoisting weirdness (“you don’t want that weirdness in your life” — the 30-second version of 027’s var/let lesson), first-class functions/closures/this, prototypes with class as syntactic sugar, the event loop (callbacks → promises → async/await), modules and npm, imperative DOM (querySelector, addEventListener) vs declarative frameworks, and bundlers (Vite/Webpack) with code-splitting via dynamic import(). Pairs with 028: Fireship covers prototypes in 60 seconds, ColorCode spends 20 minutes — point learners there for depth.

Screenshot refs: frames-lkIFF4maKMU/frame_00026.png (JS logo card), frame_00030.png (interpreted-language diagram), frame_00040.png (callback diagram), frame_00045.png (DOM tree), frame_00050/00055.png (framework resource lists).

Full narrative: 030 — 100+ JavaScript Concepts You Need to Know (the 12-minute checklist) — the complete lesson with all 6 screenshots, code blocks, and transcript corrections.


101 — THINK in Code: the Hard Parts of JavaScript (x7u2c0DhWEU, ~4:40:36)

The internals companion to 027 and 030: a freeCodeCamp compilation of deep-dive JavaScript concept lessons aimed at an “engineering-grade mental model.” Scope chains and closures (the for-loop var trap), the interpreter model with global execution context and hoisting, prototypes and constructor functions, this/classes/inheritance, event bubbling, call-stack traces, memoization, reduce-style accumulators, then the finale block — web workers, blocking vs non-blocking routes, and Node.js on LibUV (single-threaded JS over multi-threaded IO). No TypeScript syntax; everything here is runtime behavior TypeScript later constrains.

var num1 = 2;
function sum() {
	return function () {
		return num1; // closure keeps the outer reference alive
	};
}

Screenshot refs: frame-0001.png (closure code) through frame-0007.png (LibUV thread diagram) — execution context, prototype, Player class, call stack, worker console, LibUV.

Full narrative: 101 — THINK in Code: Hard Parts of JavaScript (closures to LibUV) — the complete lesson with all 7 screenshots, code blocks, and transcript corrections.


102 — Modern JavaScript Full Beginner Course (oQlrw-xViA8, ~4:04:46)

Conner Ardman’s four-hour beginner course, taught entirely through live coding in VS Code (Code Runner + Live Server): console.log and let/const/var with the early coercion lesson (== vs ===), if/else and switch plus for/while/do...while with break/continue, declarations and arrow functions, objects (dot access, reference mutation) and arrays (forEach/map/filter/reduce), then the web pivot — getElementById/querySelector, innerHTML, addEventListener for click/keyboard/scroll — closing on try/catch/finally, strict mode, ASI, and typeof (including the typeof [] === "object" gotcha). The syntax prerequisite to 101’s internals: every annotation from module 01 onward constrains exactly these behaviors.

let isSignedIn = true;

if (isSignedIn) {
	// welcome path
}

Screenshot refs: frame-0001.png (editor setup) through frame-0007.png (DOM files) — conditionals, variables, array map, typeof, one shot per course section.

Full narrative: 102 — Modern JavaScript Full Beginner Course (Conner Ardman, setup to DOM) — the complete lesson with all 7 screenshots, code blocks, and transcript corrections.


112 — JavaScript Is Dead (Sh5B7ApPh7k, ~19:10)

Web Dev Simplified steelmans the title objection — “JavaScript is one of, if not the most popular programming language, but it’s actually dying, and the reason for that is because of TypeScript” — then prosecutes chart by chart: State of JS flavors climbing from 25% (2016) to 78% (2020) with pure TypeScript at 67% by 2025; non-adopters concentrated in 30-plus-year veterans on legacy codebases while top earners skew TypeScript (~73% near-total use above $200k); an Indeed scrape of ~89k React-plus-TypeScript postings against ~39k React-plus-JavaScript; a peer-reviewed IRJMES study (10 devs, 100k-plus lines) showing 17.3% fewer mistakes and 31% faster bug fixes; npm at ~95M weekly TypeScript downloads with ~88% of top-1000 packages shipping types. Closes with the one-day syllabus: definitions, functions, modifiers, narrowing — defer generics and tuples. Watch first: the syllabus order places 113 and 111 in the middle and 110 in the deferred tier.

const typeScriptAdvantage = {
	fewerMistakes: "17.3%",
	fasterBugFixes: "31%",
	fasterDevelopment: "18.9%",
	fasterOnboarding: "27%",
} as const;

Screenshot refs: frame-0001.png (journal PDF) through frame-0005.png (course syllabus) — adoption charts, paper results, npm audit, syllabus.

Full narrative: 112 — JavaScript Is Dead (adoption data, hiring market, one-day syllabus) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


114 — Strict TypeScript Is Not Enough (35cESnxXH6o, ~21:24)

Web Dev Simplified on the sixteen tsconfig flags beyond strict — “Most developers think that enabling strict mode in TypeScript is enough to solve all of their problems, but this file on the left here is absolutely full of type errors, but not a single one is getting an error or a warning.” The ladder runs four tiers: move-proof "@/*" path aliases, then the no-brainer hygiene tier (noUnusedLocals, noUnusedParameters, allowUnusedLabels: false, noUncheckedSideEffectImports, noFallthroughCasesInSwitch, allowUnreachableCode: false), then the opt-in safety tier (noUncheckedIndexedAccess, noPropertyAccessFromIndexSignature, erasableSyntaxOnly), then personal preference (noImplicitOverride, exactOptionalPropertyTypes, noErrorTruncation as a debugging lens only) — closing on the allowJs/checkJs/@ts-check migration tail where JavaScript checking stays opt-in. Pairs with 115 (single rungs become a program) and 116 (hygiene enforced mechanically).

{
	"compilerOptions": {
		"noUncheckedIndexedAccess": true,
		"noPropertyAccessFromIndexSignature": true,
		"allowJs": true,
		"checkJs": false
	}
}

Screenshot refs: frame-0001.png (course-page open) through frame-0004.png (migration tail) — sponsor beat, correctness tier, safety tier, JS staging.

Full narrative: 114 — Strict TypeScript Is Not Enough (16 tsconfig flags in four tiers) — the complete lesson with all 4 screenshots, code blocks, and transcript corrections.


118 — Setup, Annotations, Arrays (AqIxec1p7Xg, ~55:30)

Coding Addict’s fundamentals leg one out of a single tutorial.ts inside a Vite vanilla-TS scaffold — Excalidraw roadmap (Fundamentals leads to React leads to Store) at the open, localhost:5173 in the middle, README challenge checklists between beats: “well, once I built my first project with TypeScript, it was very hard to go back and build with just vanilla JS.” The ground floor the rest of the batch assumes: the superset mental model, the npm create vite@latest -- --template vanilla-ts reality, generic DOM lookups, the tsc deploy gate (dev runs with errors, build fails), annotations versus inference, the any propagation warning, unions and literals, the foundBook: string | undefined search arc with ?., and typed arrays through the inference-widening gotcha that motivates 117. On-ramps to 115 (literals to unions) and 114 (warnings to law).

let foundBook: string | undefined; // honest type: miss means undefined
console.log(foundBook?.toUpperCase()); // ?. per the possibly-undefined error

Screenshot refs: frame-0001.png (roadmap) through frame-0005.png (array close) — scaffold, drill, search, pushes.

Full narrative: 118 — Setup, Annotations, Arrays (Vite scaffold to typed pushes) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


152 — What is Node.js? JavaScript Back-End Tutorial (P-fDVxjSXEw, ~08:14)

Coding2GO’s runtime prerequisite: “Node.js is not a programming language. It is a server-side runtime environment.” One language, two runtimes — then what relocation unlocks: bcrypt hashing in one call (“Just use an NPM package called Bcrypt and call a single function to encrypt the password”), filesystem scripts outside the browser (“Hello World is now printed to the console”), and the six-line http server (“response.write hello world and we also end the response with response.end”) every framework wraps. Sequencing advice is explicit — learn JavaScript before frameworks — a roadmap 157 also preaches.

// the primitive every framework wraps
const http = require("http");
const server = http.createServer((req, res) => {
	res.writeHead(200, { "Content-Type": "text/plain" });
	res.end("Hello, World!\n");
});
server.listen(3000, () => {
	console.log("Server running at http://localhost:3000/");
});

Screenshot refs: frame-0001.png (bcrypt hashing) through frame-0004.png (framework search) — 4 sampled frames in order (source frames 2, 4, 6, 8); the opening bumper frame shows unrelated Sass and Chrome icons and is excluded.

Full narrative: 152 — What Is Node.js (runtime, npm, scripts, HTTP server) — the complete lesson with all 4 screenshots, code blocks, and transcript corrections.


153 — Node.js: The Documentary (LB8KwiiUGy0, ~62:48)

CultRepo’s origin film for the runtime 152 teaches: Dahl’s async bet (“You start thinking about Ruby on Rails, why is that slow?”) against a 2009 web where “interactive websites and stuff was basically non-existent”, the stage demos that made non-blocking I/O visible, npm compounding isolated users into an ecosystem (“It did build on my machine” notwithstanding), the growth chart quantifying 2010–2014 ascent, and the io.js fork forcing foundation governance (“So a lot of us have been very involved in that”). Technical, social, and political beats — each necessary, none sufficient alone.

// the bet: start the read, continue on callback, never block
const fs = require("fs");

fs.readFile("example.txt", "utf8", (err, data) => {
	if (err) throw err;
	console.log(data);
});

Screenshot refs: frame-0001.png (conference stage) through frame-0005.png (Interactive 2015) — 5 sampled frames in order (source frames 1, 7, 11, 30, 56); a documentary, so stages, interviews, and slides rather than editor sessions.

Full narrative: 153 — Node.js, The Documentary (Ryan Dahl, async I/O, io.js, foundation) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


154 — TypeScript Setup for Node.js with VS Code & PM2 (BLoFPda7fmI, ~15:55)

Zaiste Programming’s three-stage pipeline: write typed code with editor support (“The biggest feature is the type system which means that you can add types to your programs”), transpile source-to-source (“Transpilation is a special case of compilation”) while letting inference carry locals (“You should let TypeScript compiler to guess the types for you”), close Node’s type gap (“Because Node.js is not written in TypeScript, there is no type information”) with the DefinitelyTyped install 149 names, and run production under PM2 (pm2 start dist/main.js -i max). The typed setup 155 replays with Express added.

npm install --save-dev @types/node

Screenshot refs: frame-0001.png (empty workspace) through frame-0006.png (PM2 production) — 6 sampled frames in order (source frames 1, 6, 8, 9, 11, 16).

Full narrative: 154 — TypeScript Setup for Node.js (VS Code, inference, @types, PM2) — the complete lesson with all 6 screenshots, code blocks, and transcript corrections.


155 — How To Use TypeScript With Express & Node (qy8PxD3alWw, ~17:04)

Colt Steele’s layered build: working JavaScript Express first (“Hello from express plus TS” before types enter), then typescript @types/express @types/node (“We want typescript here, so I need to install the type declarations for typescript”), tsc --init with outDir aimed at dist (“I’ll change that to something like dist”), then the script tiers — build emits (“that will get me my JavaScript files”), dev watches plus nodemon, rimraf dist wipes stale emit (“a script for my build instead of just doing NPX”), and concurrently parallelizes watch plus restart cross-platform. The production instance of 149’s lesson.

{
	"scripts": {
		"build": "npx tsc",
		"start": "node dist/index.js",
		"dev": "npx tsc -w & nodemon dist/index.js"
	}
}

Screenshot refs: frame-0001.png (plain Express app) through frame-0006.png (concurrent serve) — 6 sampled frames in order (source frames 3, 5, 8, 11, 14, 16).

Full narrative: 155 — TypeScript with Express and Node (tsc init, scripts, rimraf, concurrently) — the complete lesson with all 6 screenshots, code blocks, and transcript corrections.


156 — JavaScript Visualized - Event Loop, Web APIs, (Micro)task Queue (eiC58R16hb8, ~12:34)

Lydia Hallie’s animated async model: five actors (stack, Web APIs, task queue, microtask queue, event loop) behind one notorious topic (“when we zoom out, it’s just a” coordination mechanism). Sync runs to completion while blockers starve (“we first have console log one. So a new” frame pushes first); long work offloads to the browser (“allow us to offload long running tasks”); timers resolve by delay, never writing order; and the loop drains microtasks first (“the event loop prioritizes the micro task queue”) — promises and queueMicrotask ahead of every setTimeout. The theory behind 153’s platform bet, animated.

Promise.resolve().then(() => console.log("1"));
setTimeout(() => console.log("2"), 10);
queueMicrotask(() => console.log("3"));
console.log("5");

Screenshot refs: frame-0001.png (runtime diagram) through frame-0005.png (priority diagram) — 5 sampled frames in order (source frames 1, 2, 4, 6, 7).

Full narrative: 156 — Event Loop, Web APIs, Task Queues (JavaScript visualized) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


157 — How to Learn JavaScript FAST in 2026 (kJf4MmouR-s, ~12:09)

Coding Elf’s study plan for the module: the 98.9-percent motive (“JavaScript runs on 98.9% of all websites”), then retrieval over recognition (“going yes, I get it” — then close the tutorial and reproduce from memory), rotation over cramming (“Every time you recall it, it sticks a little deeper”), context over exercises (“The concepts only click when you use them in context” — build the counter), and AI as explainer (“Use it like a mentor that’s available at 2 am”) with the learner still writing the code. Pairs with 152’s JS-first sequencing; points at 027 for the full course.

// the context drill: state plus DOM, wired by hand
let count = 0;
document.getElementById("counter").innerText = count.toString();

function increment() {
	count++;
	document.getElementById("counter").innerText = count.toString();
}

Screenshot refs: frame-0001.png (credential close-up) through frame-0005.png (builders close) — 5 sampled frames in order (source frames 1, 2, 4, 6, 9); a presenter-plus-animation video, so scenes and graphics rather than editor sessions.

Full narrative: 157 — How to Learn JavaScript Fast (recall, repetition, projects, AI mentors) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.

↑ contents


022 — #1 - What is TypeScript || Install Typescript || TypeScript vs JavaScript (GrL86rlRvpA, ~17:31, Naveen AutomationLabs)

This video introduces TypeScript as a statically typed superset of JavaScript, developed by Microsoft and designed to enhance developer productivity and code reliability. It covers the basics of TypeScript, including its static typing, type inference, and compilation process. The video also guides viewers on how to install TypeScript globally using npm and highlights the benefits of using an IDE

Full narrative: 022 — #1 - What is TypeScript || Install Typescript || TypeScript vs JavaScript (what, why, install walkthrough)


053 — #19 Configuring TypeScript Compiler | Configuring TypeScript Compiler | A Complete TypeScript Course (QJSi_OnLYw4, ~12:06, procademy)

The lecture solves two scaling pains of the tsc <file> workflow: recompiling by hand after every edit, and compiling only one file at a time. Fix one is watch mode — tsc app.ts --watch (or -w) keeps a process running that recompiles on every save, until Ctrl+C kills it. Fix two is project mode: with app.ts, config.ts, and auth.ts each logging a line and each .js linked from `index.ht

Full narrative: 053 — #19 Configuring TypeScript Compiler | Configuring TypeScript Compiler | A Complete TypeScript Course (tsc –init and watch)


054 — #20 Including & Excluding Files | Configuring TypeScript Compiler | A Complete TypeScript Course (Kn5N2o2e24A, ~11:21, procademy)

The lecture tours the file-selection side of tsconfig.json: exclude (array of paths to skip), include (array of paths to compile, everything else skipped), and files (individual files only, no folders). Each gets a live demo against the three-file project (app.ts, auth.ts, config.ts): excluding config.ts stops config.js from regenerating (which breaks the index.html link — the

Full narrative: 054 — #20 Including & Excluding Files | Configuring TypeScript Compiler | A Complete TypeScript Course (file selection)


055 — #21 Setting a Compilation Target | Configuring TypeScript Compiler | A Complete TypeScript Course (BquCRg4hTv0, ~06:59, procademy)

The lecture covers a single compilerOptions property — target — which tells the TypeScript compiler which version of JavaScript to emit. Starting from ES2016, the presenter declares a string variable and a numeric constant in app.ts, compiles, and shows app.js using let/const. Switching target to ES5 recompiles the same code to var declarations, because let/const arrived

Full narrative: 055 — #21 Setting a Compilation Target | Configuring TypeScript Compiler | A Complete TypeScript Course (emit version)


056 — #22 Setting Core Lib for TypeScript | Configuring TypeScript Compiler | A Complete TypeScript Course (q5EQ89JQA9c, ~08:30, procademy)

The lecture covers the lib compiler option: the set of bundled library declaration files that tells TypeScript which features and runtime APIs a project may use. The demo adds a <button id="BTN"> to index.html, grabs it in app.ts with document.getElementById, and attaches a click listener — then asks how TypeScript knows document, getElementById, and addEventListener at all, give

Full narrative: 056 — #22 Setting Core Lib for TypeScript | Configuring TypeScript Compiler | A Complete TypeScript Course (known APIs)


068 — Is Learning TypeScript A Waste Of Time? (GhKFQOA28Nk, ~08:32, Web Dev Simplified)

Kyle’s provocation: going deep on TypeScript is a waste of time for day-to-day code — 99% of features go unused outside complex type-safe libraries, and the rare exotic need is one search away. Proof by walkthrough across four real projects: a two-file script, a React app, a larger multi-file project, and a Next.js + Firebase app. In each, the TypeScript-specific surface is the same three things:

Full narrative: 068 — Is Learning TypeScript A Waste Of Time? (the adoption case)


158 — TypeScript Makes You A Faster Developer (7P9sxqt7HfA, ~09:14, Web Dev Simplified)

Kyle rebuts the standard complaint — types slow you down, especially on small or greenfield projects — with a live side-by-side: the same click-handler and component code in JavaScript vs TypeScript, keystroke for keystroke. The TypeScript wins compound: typed parameters restore full autocomplete inside every function (one added word pays back every call site), querySelector’s Element | null f

Full narrative: 158 — TypeScript Makes You A Faster Developer (velocity argument)


159 — Node JS Full Course 2026 | Complete Backend Development Course | 17 Hours (XdH3gpcwnoA, ~1026:52, Sangam Mukherjee)

This course provides a comprehensive overview of Node.js and backend development, covering essential topics such as runtime environments, core modules, asynchronous programming, file systems, HTTP servers, and database integration. It also delves into advanced concepts like TypeScript, middleware, authentication, caching with Redis, rate limiting, and background job processing using tools like Bul

Full narrative: 159 — Node JS Full Course 2026 | Complete Backend Development Course | 17 Hours (backend runtime course)


module 01 — fundamentals

Narratives: 001B · 020 · 098 · 029 · 040 · 024 · 025 · 026 · 032


001B — Types, Functions, Objects (d56mG7DezGs, Part B of 1:04:28)

Module-01 half of the same lesson. Built-ins recap: JavaScript gives number, string, boolean, null, undefined, object; TypeScript adds any, unknown, never, enum, tuple (any/enum/tuple covered here). Primitives with inference: annotate only when declaring without initializing, otherwise let the compiler infer. any is the escape hatch (uninitialized let level; falls back to it) — noImplicitAny (on via strict) flags it, and the video warns against turning the check off project-wide. Arrays narrow element types (number[] rejects '3') and unlock IntelliSense; tuples fix length and per-position types ([number, string] pairs) but can leak on push since they compile to plain arrays. Enums list related constants (enum Size { Small, Medium, Large }, prefer const enum for optimized emit).

Functions always annotate params and return type; the compiler enforces arity, with optional (taxYear?: number) and default (= 2022) parameters, noImplicitReturns for uncovered branches, and noUnusedLocals/noUnusedParameters for dead declarations. Objects take inline shape annotations with readonly and ? modifiers, but repeated shapes move to a type alias (PascalCase). Unions (number | string) widen; intersections (Draggable & Resizable) combine; typeof/instanceof narrowing precedes type-specific use; strictNullChecks stays on with ?. optional chaining (customer?.birthday?.getFullYear()) for possibly-absent values. Screenshot refs: videos/d56mG7DezGs/frames/frame-0022.jpg (type Quantity = 50 | 100, type Metric = 'cm' | 'inch'); all other snippets reconstructed from the transcript.

Full narrative: 001 — TypeScript Tutorial for Beginners (part B: types, functions, objects) — the complete lesson with the code screenshot, module checklists, and transcript corrections.


020 — Tuples (tHSstkiVbc8, 6:50)

The last built-in type of the fundamentals run, and the direct sequel to 005. Arrays taught inferred element types with free positioning; this lesson adds the one constraint that makes a tuple a tuple — once a position is declared as a type, that position keeps that type. Same square-bracket syntax, same array methods, but per-position types fixed at declaration. The lesson closes by spending the idea in real project code: a tuple plus the spread operator removes a duplicated constructor call.

arrays recap — any member type in any position

The starting point is a mixed array, the union-widening case from 005. let arr = ['ryu', 25, true] infers (string | number | boolean)[], so every position accepts every member type: arr[0] = false (string slot takes a boolean) and arr[1] = 'yoshi' (number slot takes a string) both compile, and wholesale reassignment like arr = [30, false, 'yoshi'] is fine as long as each element matches one of the three.

let arr = ["ryu", 25, true]; // (string | number | boolean)[]
arr[0] = false; // ok — boolean is a member of the union
arr[1] = "yoshi"; // ok — string is a member of the union
arr = [30, false, "yoshi"]; // ok — every element matches the union

Flexible, but position-blind: nothing stops the name slot from holding a number. Screenshot refs: tHSstkiVbc8_frame_001.png (mixed arr starter, ~0:00:58) through tHSstkiVbc8_frame_002.png (element writes, ~0:01:57).

declaring a tuple — explicit per-position types

A tuple must be annotated explicitly — without the annotation the compiler reads the initializer as a plain array. The annotation lists the expected type of each position inside square brackets:

let tup: [string, number, boolean];
tup = ["ryu", 25, true]; // ok — string, number, boolean in order
// tup = [40, 'ryu', true]; // error — position 0 must be string, position 1 must be number

Swap the first two elements and the compiler rejects it: position 0 was declared string, position 1 was declared number, and neither accepts the other’s type. That rejection is the whole lesson in one squiggle — the declared order is a contract, not a suggestion.

Screenshot refs: tHSstkiVbc8_frame_002.png (tuple annotation introduced, ~0:01:57) through tHSstkiVbc8_frame_003.png (valid initializer, ~0:02:55).

element reassignment — same type only

The position rule applies to writes as well as to initialization. tup[0] = 'ken' compiles (string into a string slot) and tup[1] = 30 compiles (number into a number slot), but tup[0] = false fails — a boolean can never occupy position 0 — and tup[1] = 'yoshi' fails for the mirror reason.

tup[0] = "ken"; // ok — string into a string position
tup[1] = 30; // ok — number into a number position
// tup[0] = false;  // error — boolean not assignable to string
// tup[1] = 'yoshi'; // error — string not assignable to number

Screenshot refs: tHSstkiVbc8_frame_003.png (reassignment attempts, ~0:02:55) through tHSstkiVbc8_frame_004.png (passing and failing writes, ~0:03:54).

semantic positions — the student example

The motivating pattern: positions with meaning. A student record is a tuple whose first element is always the name and whose second is always an id number:

let student: [string, number];
student = ["chun-li", 30]; // ok — name first, id second
// student = [30, 'chun-li']; // error — string must come first, number second

Because the order is enforced, later code can rely on it — student[0] is always the name string, student[1] is always the number — with no runtime checks. Screenshot refs: tHSstkiVbc8_frame_004.png (student tuple, ~0:03:54).

project application — a values tuple plus spread

The lesson lands in the Finance Logger project code, where two constructor calls repeat the same three arguments (to.value, details.value, amount.valueAsNumber). The first attempt collects them into a plain array:

let values = [to.value, details.value, amount.valueAsNumber];
new Invoice(...values); // error — spread of (string | number)[] matches no constructor overload

The failure is precise: an array only promises “each element is a string or a number”, so the spread could hand the (client: string, details: string, amount: number) constructor its arguments in any type order. Annotating the tuple restores the guarantee:

let values: [string, string, number];
values = [to.value, details.value, amount.valueAsNumber];
new Invoice(...values); // ok — string, string, number in order
new Payment(...values); // ok — same three parameters

Now the compiler knows position 0 is a string, position 1 is a string, position 2 is a number, and the spread satisfies both constructors — the duplicated argument lists collapse into one shared ...values. This is the module-05 payoff in miniature: the tuple knowledge from the fundamentals run removes real repetition in the project code. Screenshot refs: tHSstkiVbc8_frame_005.png (values array with spread error, ~0:04:53) through tHSstkiVbc8_frame_006.png (tuple annotation, both call sites fixed, ~0:05:51).

Full narrative: 020 — Tuples (per-position types and spread into constructors)


098 — Tuples, Expanded Edition (tHSstkiVbc8, ~6:50)

Expanded edition of the tuples lesson, from the bootcamp transcript pass. Position-blind array first (arr = ['ryu', 25, true] infers a union — every position accepts every member type), then the annotated tuple (tup: [string, number, boolean], “once each position has been defined as a type like this, then that position can’t be anything else”) with same-type-only writes, the semantic student record ([string, number] — name first, id second), and the project payoff: values: [string, string, number] spread (...values) into both constructors — “we can say that this must be a tuple.”

Screenshot refs: frame-0001.png (mixed arr starter) through frame-0007.png (tuple annotation, both call sites fixed) — union writes, per-position errors, student record, values spread.

Full narrative: 098 — Tuples (per-position types, student records, and the values spread) — the complete lesson with all 7 screenshots, code blocks, and transcript corrections.


029 — You Don’t Know JavaScript (QK-RxEEVAWs, ~22:59)

The “why types” motivation video wearing a comedy costume. Every quirk it tours — float rounding, coercion, == vs ===, silent semicolon insertion, null vs undefined, string-sort — is a runtime surprise that TypeScript’s static checking exists to catch. Closing punchline, verbatim: “use a tool like TypeScript … that does static analysis to improve your code quality.” (Reaction format: the host pauses a scripted essay to riff, so conceptual claims track the underlying piece; asides are host opinion.)

Cautionary-example bank: 0.1 + 0.2 is 0.30000000000000004 (IEEE 754, not JavaScript’s fault — shared across languages); + coerces to string when either side is a string (use it only for known numbers); == coerces across types ("1" == 1 is true) — a 10-day-build compromise for early adopters that can never be removed, so avoid it at all costs; ASI is unreliable (a newline after return returns undefined — always write semicolons); typeof null is "object" (the famous lie); NaN !== NaN (test with Number.isNaN); default sort() stringifies (toSorted inherits the trap — always pass (a, b) => a - b).

0.1 + 0.2; // 0.30000000000000004 — IEEE 754, every language does this
"1" == 1; // true — loose equality coerces; use === always
[-4, -3, 17, 77, 100].sort((a, b) => a - b); // numeric order needs a comparator

Screenshot refs: frames-QK-RxEEVAWs/frame_00001.png (single vs double precision), frame_00005–00011.png (fixed-point range collapse, float gaps), frame_00012.png (String.prototype.concat docs), frame_00014.png ("1" vs 1 demo), frame_00018.png (missing-semicolon TypeError), frame_00022.png (== vs === origin story).

Full narrative: 029 — You Don’t Know JavaScript (the why-types motivation) — the complete lesson with all 10 screenshots, code blocks, and transcript corrections.


040 — Tuples in TypeScript (YzlfN5Tidy4, ~09:42)

ProAcademy second take on tuples, complementing 020. Same structure — fixed length, ordered, specific type per position — on an employee record ([number, string, number, boolean] = [123, "John", 2000, true]). The compiler rejects a 5-element assignment, a 3-element assignment, and a wrong-typed first element, then the gotcha 020 never mentions: employee.push(100) on a full tuple produces no error and silently grows it to 5 elements. Tuples compile to plain JavaScript arrays — a design-time constraint, not a runtime structure. Rule of thumb: use a tuple over an array when you want strictness (fixed length plus per-position types).

Screenshot refs: frame_0001.png (title slide); frame_0002.png talking-head (the push and reassignment demos are code-only in the transcript).

Full narrative: 040 — Tuples in TypeScript (fixed length, per-position types, and the push gotcha) — the complete lesson with code blocks and transcript corrections.

↑ contents


024 — #01 Introduction to TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (yba10v2F5TI, ~11:07, procademy)

The video introduces TypeScript as a statically typed superset of JavaScript, offering enhanced type safety and additional features like interfaces and access modifiers. It explains that TypeScript compiles to JavaScript, allowing developers to write more robust and maintainable code. The compiler enforces type rules, which helps catch errors early in the development process. While TypeScript adds

Full narrative: 024 — #01 Introduction to TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (course opener, types ahead)


025 — #02 Installing & Using TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (crH6557lVlI, ~11:20, procademy)

This video introduces the basics of installing and using TypeScript, focusing on its role as a superset of JavaScript. TypeScript requires separate installation and compilation to JavaScript for execution. The TypeScript compiler (tsc) is used to convert .ts files into .js files, which can then be run in browsers or environments that support JavaScript. The video also covers setting up a pro

Full narrative: 025 — #02 Installing & Using TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (install and first compile)


026 — #03 Variables in TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (ucNZ6LUe8KA, ~10:56, procademy)

This video introduces the fundamentals of variables in TypeScript, emphasizing the differences between JavaScript and TypeScript in terms of typing. It covers variable declaration using let and const, type inference, and naming conventions. The video also explains the concept of static typing in TypeScript compared to JavaScript’s dynamic typing. Key takeaways include understanding how variabl

Full narrative: 026 — #03 Variables in TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (declaring variables)


032 — #04 Datatypes in TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (Qb15y2BV42Y, ~14:12, procademy)

This video introduces the fundamental data types in TypeScript, including strings, numbers, and booleans. It explains how to create strings using different quotation marks and how to use template literals for embedding variables. The number type is covered, highlighting that all numeric values are stored as floating-point numbers. The boolean type and its truthy/falsy values are also discussed

Full narrative: 032 — #04 Datatypes in TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (core data types tour)


module 02 — type system

Narratives: 009 · 087 · 019 · 097 · 028 · 037 · 041 · 042 · 103 · 104 · 105 · 106 · 109 · 111 · 113 · 115 · 117 · 120 · 043 · 044 · 045 · 046 · 047 · 048 · 051 · 135 · 146 · 147 · 148 · 149 · 150 · 151 · 033 · 034 · 035 · 036


009 — Type Aliases (AmpwfbdFYL8, ~3:03)

Repeated inline parameter types (string | number, { name: string, uid: string | number }) get named once with type and reused: type StringOrNum = string | number; applied to logDetails, and type objWithName = { name: string; uid: StringOrNum; } (composing the first alias) applied to greet. Aliases are compile-time names only — identical emitted JavaScript. Screenshot refs: videos/AmpwfbdFYL8/frames/f_001.png (title card) through f_006.png (finished state with both aliases).

Full narrative: 009 — Type Aliases (naming unions and object shapes with type)


087 — Type Aliases, Expanded Edition (AmpwfbdFYL8, ~3:03)

Expanded edition of the aliases lesson, from the bootcamp transcript pass. The shortest lesson in the series — one idea applied twice: repeated inline types (uid: string | number, { name: string, uid: string | number }) get named once (type StringOrNum = string | number; — “So now instead of writing it out here, I could just say, string or num like this”) and composed (type objWithName = { name: string; uid: StringOrNum; }) across logDetails and greet. Aliases are compile-time names only — identical emitted JavaScript.

Screenshot refs: frame-0001.png (repeated inline types) through frame-0003.png (both aliases applied).

Full narrative: 087 — Type Aliases (name it once: StringOrNum and objWithName) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.


019 — Enums (r8G7-hQG07o, ~3:24)

The one idea: stop memorizing magic numbers. A generic Resource<T> with a numeric resourceType field forces callers to pass raw codes (resourceType: 3) and consult an external index to learn that 3 means book — workable for two codes, unmaintainable beyond that. One declaration fixes it: enum ResourceType { BOOK, AUTHOR, FILM, DIRECTOR, PERSON } binds each descriptive name to an auto-assigned number, and retyping the field as resourceType: ResourceType narrows callers to ResourceType.BOOK-style members with autocomplete listing every option. Call sites read like English (docOne uses ResourceType.BOOK, docTwo uses ResourceType.PERSON) while the compiler stores compact numbers — logging shows 0 and 4, since members auto-number from zero in declaration order. The generic data: T parameter is untouched: enums and generics compose freely. Explicit value assignment and string enums are not covered here. Screenshot refs: frames/r8G7-hQG07o/frame_0002.png (full lesson code — enum, interface, both documents) and frame_0004.png (zero-index numbering point); frame_0001.png / frame_0003.png show the Finance Logger preview pane only, not lesson code.

Full narrative: 019 — Enums (named constants with auto numeric values)


097 — Enums, Expanded Edition (r8G7-hQG07o, ~3:24)

Expanded edition of the enums lesson, from the bootcamp transcript pass — the shortest Net Ninja lesson in the set. Numeric resourceType codes (3 means book, 4 means person — “consult the index”) become enum ResourceType { BOOK, AUTHOR, FILM, DIRECTOR, PERSON }, and retyping the field as resourceType: ResourceType narrows callers to named members with autocomplete. Call sites read like English while the compiler stores numbers: “It says a number, 0 for book, and 4 for person, that’s because this is 0 index” — “Now we no longer have to maybe remember what number to use for a resource type.”

Screenshot refs: frame-0001.png (numeric codes on both documents) through frame-0003.png (console showing 0 and 4) — all 3 captioned frames.

Full narrative: 097 — Enums (ResourceType named constants with auto-numbering) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.


028 — Inheritance in JavaScript: Prototypal Inheritance (jnME98ckDbQ, ~20:06)

ColorCode episode on what happens when objects share structure — inheritance strictly as duplication removal, and the conceptual prerequisite for TypeScript’s extends, implements, and interface inheritance (every class pattern here is prototype delegation underneath). Two-problem framing: identical talk() on me and you duplicates code today and multiplies every fix tomorrow. Inheritance fixes both: write once, repair in one place.

Key mechanics: class Person with talk() is taught first as the readable form, then opened in the console — no talk on the instance, only __proto__, and the identity check Person.prototype === me.__proto__ is true. Patching Person.prototype.talk fixes every instance at once. Convention falls out: state on this in the constructor (own properties like this.age = 12), behavior on the prototype (shared methods). class Superhuman extends Person borrows talk plus its own fly() — one-directional, parents never see children. new-free equivalents: Object.create(person) and Object.setPrototypeOf(me, person). Applied close: shared component base classes, React class components extending React.Component, Web Components extending HTMLElement.

Person.prototype === me.__proto__; // true — same object
class Superhuman extends Person {
	fly() {
		return "flying to the moon";
	}
}

Screenshot refs: both captioned frames are talking-head (non-technical); all code evidence comes from the narrated console sessions in the full narrative.

Full narrative: 028 — Inheritance in JavaScript: Prototypal Inheritance (write once, fix once) — the complete lesson with both screenshots, code blocks, and transcript corrections.


037 — Type Assignment & Type Inference (PVu2jNMb6Y8, ~14:00)

ProAcademy lecture on explicit types and inference, built on a sum(num1, num2) demo. Untyped parameters silently accept sum("12", 13) and produce "1213"; annotating (num1: number, num2: number) turns it into a compile-time error (“as simple as this” vs JavaScript if-statement sanitization). Removing the annotations shows inference: hovering n1 reveals number fixed from the 10 initializer, permanently — n1 = "hello" errors. The .js side-by-side locks the vocabulary: TypeScript is strongly typed (inferred type cannot change), JavaScript is dynamically typed (type follows the last assignment). Closes by extending sum with an isPrint: boolean flag and a message: string parameter.

Screenshot refs: frame_00001.png (title slide), frame_00002.png (Type Inference definition slide), frame_00003.png (VS Code sum code), frame_00004.png blank talking-head.

Full narrative: 037 — Type Assignment & Type Inference (explicit types, and the type that locks in) — the complete lesson with code blocks and transcript corrections.


041 — Enums in TypeScript (KAkSZYN08ak, ~08:58)

ProAcademy second take on enums, complementing 019. The motivation ladder runs string role ("admin", unconstrained free text) → scattered numeric constants (admin = 0, readOnly = 1, …) → one grouped Roles enum on a user object. Braces do not make it an object; members are unquoted named values defaulting to 0-based auto-increment. Fills 019’s gaps: explicit start values shift followers (admin = 1 → rest follow), fully custom values (100, 200, 300, trailing member becomes 301), and string/mixed members (admin = "ADMIN"). Closes where 019 never goes — the compiled output: the one-line enum emits an immediately invoked function expression (IIFE), visibly complex next to its source.

Screenshot refs: frame_0001.png (title slide); frame_0002.png blank (explicit-values demo is code-only in the transcript).

Full narrative: 041 — Enums in TypeScript (named values, auto-increment, and the compiled IIFE) — the complete lesson with code blocks and transcript corrections.


042 — The any Type (aL-X_SL7R38, ~06:34)

ProAcademy lecture on the most flexible annotation, closing the loop 037 opened: inference locks a type in, and any opts back out. A dynamicData: any demo stores a number, boolean, string, string array, and object with zero compiler complaints; an any[] holds string, number, boolean, null, and undefined side by side. The takeaway is a warning — code full of any is “almost similar to writing a JavaScript code” — avoid it unless the stored type is genuinely unknowable. Coda: unannotated, unassigned let test has both type undefined and value undefined.

Screenshot refs: frame_0001.png (Lecture 10 title slide, app.ts open); frame_0002.png blank (the typeof demo is code-only in the transcript).

Full narrative: 042 — The any Type in TypeScript (the escape hatch, and uninitialized undefined) — the complete lesson with code blocks and transcript corrections.


103 — Did He Really Fix TypeScript? (C_v0fcGEGbA, ~7:50)

Web Dev Simplified on Matt Pocock’s TS Reset: a one-import library (ts-reset.ts) that patches the standard-library types so the defaults stop lying. JSON.parse (and res.json()) goes from any to unknown, forcing a real check before property access; array.filter(Boolean) narrows [1, 2, 3, null] to number[]; includes on a readonly tuple accepts the lookup instead of over-checking. The payoff to 042’s warning — the any you never wrote, hiding inside built-in signatures — and the static-side complement to 074’s runtime Zod validation.

const json = JSON.parse('{"name": "Kyle"}');
if (typeof json === "object" && json !== null && "something" in json) {
	const something = json.something;
}

Screenshot refs: frame-0001.png (walkthrough opening) through frame-0005.png (includes demo) — JSON.parse as unknown, ts-reset.ts import, filter narrowing.

Full narrative: 103 — Did He Really Fix TypeScript? (TS Reset, unknown JSON and friendlier arrays) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


104 — Type vs Interface: the Handbook Is Backwards (oiFo2z8ILNo, ~07:44)

Web Dev Simplified argues the handbook recommendation (interfaces by default) is backwards: interfaces are more complicated with fewer features — “in my opinion, this is completely backwards because interfaces are more complicated than types, they have less features than types.” Type aliases name anything (type SType = string), spell unions (Name | Age), and combine inline with &; interfaces need a named parent for extends and merge silently on duplicate names — a footgun everywhere except the legitimate Window-extension case. The stale compiles-faster claim is ruled out; the rule is default to type, reach for interface only for declaration merging. Sets up 105 (predicates narrow union types, which are types-only) and pays off at project scale in 107.

type NameOrAge = { name: string } | { age: number };

Screenshot refs: frame-0001.png (split-screen opener) through frame-0006.png (merge demo) — declaration syntax, primitives, unions, merging.

Full narrative: 104 — Type vs Interface (default to type, merging is the one exception) — the complete lesson with all 6 screenshots, code blocks, and transcript corrections.


105 — Type Predicates Fix the Extracted-Guard Bug (Wksz1DnJ2VM, ~05:00)

Web Dev Simplified on the refactor that kills inference: an inline "email" in person check narrows the User | Employee union with autocomplete as proof, but extracting it into an isEmployee helper returning plain boolean stops all narrowing — “TypeScript is not smart enough to look inside of this function to see what’s happening.” The fix is a person is Employee return annotation, restoring both branches (the else branch narrows to the remainder, not unknown). Closes on the gotcha: a wrong predicate corrupts every call site silently, like an as cast. Follows 104 (the unions narrowed here are types-only) and is automated for the filter case by 106.

function isEmployee(person: User | Employee): person is Employee {
	return "email" in person;
}

Screenshot refs: frame-0001.png (working inline narrowing) through frame-0005.png (wrong-predicate demo) — inline proof, broken refactor, predicate fix.

Full narrative: 105 — Type Predicates Fix the Extracted-Guard Bug (person is Employee) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


106 — Four TypeScript 5.5 Upgrades (FhT87_CqPug, ~05:48)

Web Dev Simplified runs TypeScript 5.4 (left) against 5.5 (right): red squiggles on the left, clean code on the right, for all four features. Inferred filter predicates (“the array.filter method really never filtered”) plus composition through named guards; indexed-access narrowing without the temp-variable workaround; regex diagnostics for unused groups and dangling backreferences; ES2024 Set methods (union, intersection, difference) that also require an ESNext target and lib. Follows 105 (manual predicates, now inferred) and answers 103 from the compiler side — the userland filter(Boolean) patch, fixed in the language. Pairs forward with 107 (same use-the-platform instinct, Intl edition).

const nums = mixed.filter((n) => n !== null);
nums satisfies number[];

Screenshot refs: frame-0001.png (filter console demo) through frame-0005.png (Set methods plus tsconfig) — split editors, indexed access, regex, lib caveat.

Full narrative: 106 — Four TypeScript 5.5 Upgrades (inferred predicates, indexed access, regex, Set methods) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


109 — Ditching Try/Catch for Result Tuples (AdmGHwvgaVs, ~10:28)

Web Dev Simplified on why async error handling hurts: wrapping getUser in try/catch traps every consumer line inside the try, so a typo like usr routes into the same catch that handles the 404 — “Promises in async await in JavaScript are amazing, but they really suck at handling errors.” The let-hoist fix restores flat code but leaves a mutable binding, so Kyle replaces the pattern with a generic catchError returning [error, data] tuples typed Promise<[undefined, T] | [Error]>, then adds catchErrorTyped with a constructor allow-list that rethrows the unexpected. Closes on Effect as the ceiling: errors in the signature need the library. Pairs with 113 (the tuple annotation only protects callers if written down) and 111 (allow-lists for errors, brands for IDs).

const [error, user] = await catchError(getUser(2));
if (error) {
	console.log(error.message);
} else {
	console.log(user.name);
}

Screenshot refs: frame-0001.png (getUser plus terminal) through frame-0005.png (Effect website) — over-capture typo, tuple helper, typed catch, Effect close.

Full narrative: 109 — Ditching Try/Catch for Result Tuples (catchError, typed catches, Effect) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


111 — Branded ID Types (aP6w2OzidYM, ~15:48)

Web Dev Simplified on the wrong-value-of-right-type bug: getOrderInformation(user.latestSaleId) typechecks because both IDs are string, and renaming the parameter changes nothing — branded types “allow you to solve type safety problems that you can’t solve with any other method.” The fix is string & { [brand]: "InvoiceId" } behind a unique symbol (kept unimportable so the phantom key never surfaces in IntelliSense), wired into Drizzle via $type<InvoiceId>() so branding happens once at the data-access layer, generalized with Brand<T, B extends string>, and bridged to Zod with .transform((v) => v as InvoiceId) since Zod’s .brand() is Zod-local. Closes on Seconds-branded sleep. Pairs with 113 (brand the IDs and annotate the returns together) and 109 (make-invalid-states-unrepresentable, errors edition).

export type Brand<T, B extends string> = T & { [brand]: B };
export type InvoiceId = Brand<string, "InvoiceId">;

Screenshot refs: frame-0001.png (buggy call site) through frame-0006.png (Seconds use case) — brand definition, Drizzle fix, generic helper, Zod bridge.

Full narrative: 111 — Branded ID Types (nominal strings, Drizzle $type, Zod bridge) — the complete lesson with all 6 screenshots, code blocks, and transcript corrections.


113 — Return Type Annotations (63m2vvB4wo4, ~12:11)

Web Dev Simplified on when inference lies: “by default, I would recommend not using return types for any of your functions” — with three exceptions. Recursion cannot infer its own return (fibonacci collapses to any); one added return undefined branch silently widens saveUserService from User | null and breaks every caller; and tuples ([1, "Kyle"] widening to (string | number)[]), literals ("left" widening to string), and multi-branch objects (merged instead of discriminated) all lose their shape without pins. The policy: annotate library boundaries and widely-shared helpers (plus a parseable contract for AI assistants), omit file-local helpers and inline callbacks. Case study for 109’s tuple helper; pairs with 111 at one signature (Promise<InvoiceId>).

async function saveUserService(name: string, age: number): Promise<User | null> {
	if (age < 0) {
		console.log("Error");
		return null;
	}
	return saveUserDb(name, age);
}

Screenshot refs: frame-0001.png (cheat sheet) through frame-0006.png (discriminated union) — recursion, drift, policy, tuples, literals, unions.

Full narrative: 113 — Return Type Annotations (recursion, drift, tuples, literals, unions) — the complete lesson with all 6 screenshots, code blocks, and transcript corrections.


115 — Top 8 Underrated TypeScript Features (PHL4YH0HVjI, ~6:50)

Josef Bender’s countdown from five years of taking the language for granted — “I’m not talking about some crazy type gymnastics that you can achieve with TypeScript, but really just a lot of small features that add up to really boost your developer experience.” Eight small tools, no editor open, every feature a floating code card: discriminated unions with switch narrowing, as const arrays feeding typeof roles[number], one-line [string, number] tuples, template-literal TranslationKey unions factored from Lang plus Key, keyof typeof key unions from value objects, the strict: false migration ratchet, noUncheckedIndexedAccess forcing the bounds check, and declare global merging myAppVersion into Window. The breadth survey 117 generalizes (arrays to maps) and 114 programs into a ladder (single rungs to sixteen flags).

const roles = ["admin", "user", "guest"] as const;
type Role = (typeof roles)[number]; // "admin" | "user" | "guest"

Screenshot refs: frame-0001.png (talking-head open) through frame-0003.png (global close) — premise, literal tooling, augmentation.

Full narrative: 115 — Top 8 Underrated TypeScript Features (small tools, compounded DX) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.


117 — as const Routes Pattern (6M9aZzm-kEc, ~5:37)

Matt Pocock answers a live-chat question in 01-as-const.ts: a routes map hovering (property) home: string against a hand-written union — “You should not ever be doing this where you have multiple sources of truth for the same type.” He widens (a const binding freezes the reference, not the property types), narrows (as const goes deep and compile-time where Object.freeze is shallow and runtime), then derives (typeof lifts, keyof typeof takes keys, indexed access performs type-level Object.values) so a new route flows through with zero repetition. The object-map generalization of 115’s array recipe, the miniature of 116’s bottom-up design, and fully erasable so it survives the strictest flag in 114.

type RouteKeys = keyof typeof routes; // "home" | "admin" | "users" | "newUser"
type Route = (typeof routes)[RouteKeys]; // "/" | "/admin" | "/users" | "/users/new"

Screenshot refs: frame-0001.png (widening problem) through frame-0003.png (single-source close) — hover, payoff, derivation.

Full narrative: 117 — as const Routes Pattern (single source of truth from one map) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.


120 — TypeScript Enums Explained (3fXpL1O3epw, ~08:57)

Software Developer Diaries compiles every claim on camera through the chained tsc index.ts && node index.js loop — “by the end of this video, you will know everything about enums and how to use them efficiently in your code.” The arc runs from const applePrice = 10 to a valueless FruitPrices enum (members default to auto-incremented indexes, explicit numbers restart the increment), through computed members (sibling references, function calls, terminal-verified 10/50/6) and the heterogeneous-enum warning (one enum, one value type), to the const enum emit optimization and the portable as const object close that derives a literal union via keyof typeof. Pairs with 117 (the same recipe in production) and 121 (the closing object is directly Pick-able).

const fruitPrices = {
	applePrice: "TEN",
	peachPrice: "FIVE",
	bananaPrice: "TWO",
} as const;
type Prices = (typeof fruitPrices)[keyof typeof fruitPrices];

Screenshot refs: frame-0001.png (constants before) through frame-0004.png (as const close) — defaults, computed members, mixed-type warning, portable alternative.

Full narrative: 120 — TypeScript Enums Explained (defaults, computed members, const emit, as const) — the complete lesson with all 4 screenshots, code blocks, and transcript corrections.


043 — Type Narrowing with Type Guards (eox1XmhuryI, ~14:30)

Mostly Code survey: the union problem (a string | number parameter only offers shared members) fixed by typeof narrowing, then the full JavaScript-built-in ladder — truthiness for nullable unions (typeof null is "object", so a falsy pre-check splits { item: string | null } | null), Array.isArray for string | string[], the in operator (key presence even with undefined/null values, then ?? ""), instanceof for class instances (Date vs boxed String vs primitive string) — closing on TypeScript-level tools: isGlass/isExteriorWindow predicates over a shared name field with a never else-branch.

Screenshot refs: frame-0002.jpg–frame-0004.jpg (myFunction typeof demo) through frame-0010.jpg (typeof + instanceof).

Full narrative: 043 — Type Narrowing with Type Guards, Control Flow and More (typeof to predicates) — the complete lesson with 5 code screenshots, code blocks, and transcript corrections.


044 — Type Narrowing in TypeScript (WAlJfSFngxw, ~11:48)

Andrew Burgess on control flow: toNumber(value: number | string) via typeof teaches the core move including else-branch inference (after the string return, value is number with no second check). Then login(user: StandardUser | AdminUser) — direct user.isAdmin fails, so "isAdmin" in user narrows, and the early return teaches control-flow analysis (“TypeScript is very aware of the control flow of your functions”). Predicates lift narrowing out of .filter callbacks ((u): u is StandardUser), with the honest warning that return true compiles anyway — trusted, not checked; as is the weaker alternative. Finale: type: "admin" | "standard" discriminated union with a switch, a never default, a prospectUser addition that breaks the build, and a runtime throw.

Screenshot refs: talking-head only (2 frames); all code reconstructed from narration.

Full narrative: 044 — Type Narrowing in TypeScript (control flow to exhaustive switch) — the complete lesson with code blocks, verified quotes, and transcript corrections.


045 — Type-Safe TypeScript with Type Narrowing (MUJBT3Pb_Eg, ~33:36)

Rainer Hahnekamp workshop — thesis: narrowing is the most important TypeScript skill for application developers. A Date | null | undefined value in a diff-in-years calculation drives the tour: the as Date assertion is shown and rejected as “cheating … trying to be smarter than the compiler”; explicit !== null && !== undefined checks let the compiler remove the assertion itself. Each guard gets a stress test: typeof returns "object" for both Date and null (unusable); truthiness works only because Date is always truthy (adding string exposes the empty-string edge); instanceof covers class instances but not Person-shaped literals (in territory). Closes on discriminated name/kind properties, user-defined predicates (“I will trust you”), and a generic assertIsNonNullable(value): asserts value is NonNullable<T> throw-or-narrow helper.

Screenshot refs: talking-head only (3 frames); all code reconstructed from narration.

Full narrative: 045 — Type-Safe TypeScript with Type Narrowing (for application developers) — the complete lesson with code blocks, verified quotes, and transcript corrections.


046 — Type Guards & Type Narrowing Explained (h_-7E2D0lRw, ~3:24)

Code Talks three-minute intro, one loop in the Playground: printValue(value: string | number) calling value.toUpperCase() errors (Property 'toUpperCase' does not exist on type 'string | number'), one line of typeof fixes it (“TypeScript will understand fully”). Definitions verbatim: narrowing is “reducing the broader type into more specific type”; a guard is “a check that helps TypeScript determine the actual type of a value”. Closes with the series roadmap: instanceof, equality narrowing, in, truthiness, type predicates.

Screenshot refs: frame-0001.jpg (printAnimalName) through frame-0004.jpg (typeof narrowing).

Full narrative: 046 — Type Guards and Type Narrowing Explained (the three-minute intro) — the complete lesson with all 4 screenshots, code blocks, and transcript corrections.


047 — Type Widening and Type Narrowing (hXXNep-4TxA, ~17:00)

Benny Code from first principles — the ladder any → string → "hello" literal, then four widening traps each with a fix: let widens ("hello" → string, ConnectionState.Online → whole enum) while const keeps the literal; [1,2,3] widens to number[] (annotate a tuple or as const to forbid push, error 2345); unannotated return 1337 widens the inferred return (annotate : 1337); getOnlineState() returning "on" widens to string until an equality check (if (st === "on")) narrows it back at the call. Moral verbatim: “the narrower your types are, the more TypeScript can help you.”

Screenshot refs: frame-0001.jpg (widening/narrowing diagram), frame-0002.jpg (const text: "Hello").

Full narrative: 047 — Type Widening and Type Narrowing in TypeScript (keep types small) — the complete lesson with both screenshots, code blocks, and transcript corrections.


048 — TypeScript Type Narrowing Simplified (d6V4mS1Naeg, ~11:12)

Code Ryan survey — definition first (broad union → narrow), then five demos in sequence: consoleID(id: number | string) via typeof with the free else-branch (“if it’s not a string, then it’s a number”); truthiness three ways (&&, ternary, if) on string | null; in for Fish (swim) vs Bird (fly); instanceof for Date | string (toUTCString vs toUpperCase); kind-discriminated Dog | Cat (kind: "dog" | "cat", shared speak needs no guard). Closes crediting the typescriptlang.org narrowing page.

Screenshot refs: talking-head only (1 frame); all code reconstructed from narration.

Full narrative: 048 — TypeScript Type Narrowing Simplified (five guards in eleven minutes) — the complete lesson with code blocks, verified quotes, and transcript corrections.


051 — Unknown Type in TypeScript (R_vlgNxnpKQ, ~07:01)

Pairs with 042 (any): both accept assignment of any value (number, then string, then array — no compile error either way), but they differ completely on the way out. Assigning an any variable to a string compiles silently because any disables checking; assigning an unknown variable to a string errors with “unknown is not assignable to type string.” The fix is a typeof narrowing guard — only assign inside if (typeof inputVal === "string"). Moral: use unknown when the stored type is not known up front but the eventual use is, because it keeps the code type-safe where any would not.

Screenshot refs: frame-0001.png (course slide over editor); frame-0002.png talking-head (logging demo code-only).

Full narrative: 051 — Unknown Type in TypeScript (unknown vs any, typeof narrowing)


135 — Type, Type Inference, Type Annotations (-7NeC2CuuT8, ~18:20)

Naveen AutomationLabs teaches by contrast — JavaScript first, then the TypeScript fix — annotating every line with type-at-CT comments. let age; reassigned across number, string, and boolean passes silently (“this is not a statically typed language”); the colon fixes it (let fName: string holds “only and only string type of data”), while let test = "typescript" stays static with no annotation at all (“the type of data will be decided at the compile time, not at the run time”). The tour runs boolean, declarable null/undefined, any for dynamic data, enforced void and typed returns (return 123 inside void errors), and closes on fully annotated params — function add(a: number, b: number): number — with the framework motive: React, Vue, and test-automation tooling prefer TypeScript for “better readability, plus you can find the errors while writing the code instead of after running the code”.

//name: add
//params: a(number), b(number)
//return type: number
function add(a: number, b: number): number {
	return a + b;
}

Screenshot refs: frame-0001.png (JavaScript permissiveness) through frame-0008.png (documented signature) — 8 sampled frames in order (source frames 1, 3, 5, 7, 9, 12, 16, 18).

Full narrative: 135 — Type, Type Inference, Type Annotations (static proof to typed functions) — the complete lesson with all 8 screenshots, code blocks, and transcript corrections.


146 — Don’t put your types in .d.ts files (zu-EgnbmcLY, ~03:54)

Matt Pocock’s guardrail for the declaration-file run: application types belong in importable .ts modules, because .d.ts files “can’t contain runtime features. They can only contain types” and worse — “It puts things into the global scope.” The MyCodeInput module pattern beside the declare module 'xstate' ambient shape shows both sides, and the close banks the performance corollary: “That’s actually my number one TypeScript performance tip is turning on skip lib check true.”

{
	"compilerOptions": {
		"target": "es2016",
		"module": "commonjs",
		"strict": true,
		"skipLibCheck": true
	}
}

Screenshot refs: frame-0001.png (normal module) through frame-0003.png (ambient files) — 3 sampled frames in order (source frames 1, 2, 3); the closing talking-head frame carries no code and is excluded.

Full narrative: 146 — Do Not Put Your Types in .d.ts Files (declarations are not modules) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.


147 — TypeScript DTS File - What Is It For? (MbAxPjPzhRk, ~04:46)

Monsterlessons Academy’s constructive answer inside 146’s boundary: compile greet toward build.js (“And here we are saying minus minus out file build.js”) and types erase — so declaration emit (“it creates exactly this additional .dts file”) produces the type-only twin runtimes never read but compilers require. “This is totally fine” marks the payoff: with the declaration present, a TypeScript file imports the compiled library checked, and the general rule — “If we want to import it somewhere later inside TypeScript files” — covers every JavaScript library with supplied types.

// generated declaration — contract only, no body
declare function greet(person: string): string;

Screenshot refs: frame-0001.png (annotated source) through frame-0004.png (typed import) — 4 sampled frames in order (source frames 1, 2, 3, 4); the closing talking-head frame carries no code and is excluded.

Full narrative: 147 — TypeScript DTS File, What Is It For (emit, declarations, library imports) — the complete lesson with all 4 screenshots, code blocks, and transcript corrections.


148 — What Are _.d.ts Files? How to Use _.d.ts Files in TypeScript? (s_CZeWuEZ_s, ~05:48)

Maksim Ivanov’s authoring companion to 147’s emit story: extract SumArgs into a hand-written types.d.ts (“In this case, you can create a new file with d.ts extension”), import it across files (“export type some args and now we can import it in another file”), watch the unresolved import error prove the file is load-bearing (“as you can see right now, we’re having an error”), then prefer tsc example.ts --declaration generation wherever the source is yours. Closes at library scale — React’s ComponentType aliases are the same mechanism, and “It is called definitely typed if you go to types folder and open any package” points at 149.

tsc example.ts --declaration

Screenshot refs: frame-0001.png (inline type) through frame-0005.png (React aliases) — 5 sampled frames in order (source frames 1, 2, 4, 5, 6).

Full narrative: 148 — What Are .d.ts Files (hand-written types, imports, declaration emit) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


149 — TypeScript - Definitely Typed | d.ts file | Using Javascript libraries in Typescript (xNytkUB09h4, ~05:30)

Navin Balla’s ecosystem answer to 148’s hand-written declarations: “What is definitely typed and what’s its use?” A declare module 'express' map tells the compiler “the types present inside the JavaScript”, the npm @types search shows thousands of community bundles, and “that is something called as definitely typed community” closes with the one install — npm install --save-dev @types/express — after which “we can also write the back end code in the express framework completely inside the TypeScript.” The direct dependency of 155’s typed Express build.

npm install --save-dev @types/express

Screenshot refs: frame-0001.png (tutorial page) through frame-0004.png (@types results) — 4 sampled frames in order (source frames 1, 2, 4, 5); the closing talking-head frame carries no code and is excluded.

Full narrative: 149 — Definitely Typed, d.ts Files, JS Libraries in TypeScript (Express, npm) — the complete lesson with all 4 screenshots, code blocks, and transcript corrections.


150 — Learn Typescript For React - 03.01: Definitely Typed (OeZmUlz-k5Q, ~03:35)

Braedon Gough’s React-side replay of 149’s loop: import styled-components, read the missing-declaration error literally (“it couldn’t find a declaration file for this module here”), fix it with yarn add @types/styled-components (“that error is very quickly resolved”), then tour DefinitelyTyped/DefinitelyTyped — “even react itself keeps their type definition files in there” — and inherit consciously: “be aware of the different types that they export because you may or may not need to use those in your code.”

yarn add @types/styled-components

Screenshot refs: frame-0001.png (React file with the import) through frame-0003.png (DefinitelyTyped repository) — 3 sampled frames in order (source frames 2, 3, 4); the opening terminal frame shows an unrelated Python install and is excluded.

Full narrative: 150 — Definitely Typed for React (styled-components, @types, exported types) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.


151 — How Definitely Typed Changed TypeScript Forever (HyimNixYw54, ~38:52)

Callstack’s Coffee Talk history behind the infrastructure 149 and 150 assume: TypeScript won by enhancing existing code — “providing definition files to existing code, letting you enhance that code with types” — with friendlier syntax plus Microsoft backing over Flow (“TypeScript is at least better in many aspects and also just Microsoft wants it to support it”), while volunteers who “was doing a lot of JavaScript and wasn’t loving it” compounded declarations into the community warehouse. The Shape discriminated union shows the sophistication declarations eventually captured — the direct ancestor of 062.

type Shape =
	| { kind: "circle"; radius: number }
	| { kind: "square"; side: number }
	| { kind: "triangle"; base: number; height: number };

function area(shape: Shape): number {
	switch (shape.kind) {
		case "circle":
			return Math.PI * shape.radius * shape.radius;
		case "square":
			return shape.side * shape.side;
		case "triangle":
			return 0.5 * shape.base * shape.height;
		default:
			throw new Error("Unknown shape");
	}
}

Screenshot refs: frame-0001.png (story banner) through frame-0003.png (closing conversation) — 3 sampled frames in order (source frames 1, 21, 36); all frames are talking-head podcast shots with no code.

Full narrative: 151 — How Definitely Typed Changed TypeScript Forever (community, history, types) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.

↑ contents


033 — #11 Union Type in TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (h9kRkfDUCIE, ~10:52, procademy)

The lecture introduces the union type: a variable, function parameter, or return type that can hold one of several possible types, written with the pipe (|) symbol. Two demos carry the lesson. First, a getUser function whose user local is typed as an object-or-null union, modelling a database lookup that starts empty and is filled in later. Second, a printStatus(message, code) function w

Full narrative: 033 — #11 Union Type in TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (one variable, several types)


034 — #12 Literal Type in TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (IMhnIzTA2O8, ~07:36, procademy)

The lecture builds directly on the union-type session: where unions list which kinds of value a variable may hold, literal types pin down the exact value it may hold. The opening contrast is const str = "hello world" (hover type is the literal "hello world") versus let str2 = "some string" (hover type is string). The main demo is a roleMessage(role) function with a switch over `“ad

Full narrative: 034 — #12 Literal Type in TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (exact-value types)


035 — #13 Understanding Type Alias | TypeScript Basics & Data Types | A Complete TypeScript Course (dn9aUaZ2noE, ~10:47, procademy)

The lecture answers “what is a type alias”: a custom name for a type, declared with the type keyword, usable everywhere the original type was. Three reuse cases build the argument. First, the trivial type StringType = string shows the mechanics (hovering the variable still shows string). Second, the previous lecture’s printStatus union string | number becomes `type StringOrNumber = strin

Full narrative: 035 — #13 Understanding Type Alias | TypeScript Basics & Data Types | A Complete TypeScript Course (naming types)


036 — #14 Function Return Type | TypeScript Basics & Data Types | A Complete TypeScript Course (QscvAJ6vxXo, ~07:58, procademy)

The lecture covers what a function gives back. Starting from add(num1: number, num2: number), it shows TypeScript inferring the return type from the return expression (number; string once .toString() is added, number again when it is removed), then shows the explicit syntax — a colon after the parameter list — and the mismatch error (Type 'number' is not assignable to type 'string')

Full narrative: 036 — #14 Function Return Type | TypeScript Basics & Data Types | A Complete TypeScript Course (return-type annotation)


module 03 — advanced types

Narratives: 038 · 039 · 061 · 110 · 121 · 059 · 060 · 062


038 — Objects in TypeScript (zGDrjDOfyg8, ~14:46)

ProAcademy lecture on objects as contracts: initializing person = { name: "John", age: 30 } infers { name: string; age: number }, and every later assignment must match — adding gender errors with “object literal may only specify known properties,” and age: "32" errors with “type string is not assignable to type number.” Loose : object / : {} annotations accept any shape but then forbid property access; explicit inline types ({ name: string; age: number }, nested address: { city: string; country: string }) hand-write what inference produces. Type errors do not block emit — the .ts still compiles, and missing-property access prints undefined at runtime.

Screenshot refs: frame_00001.png (dual app.ts panes, known-properties error in terminal); frame_00002.png blank (the : object and nested-type demos are code-only).

Full narrative: 038 — Objects in TypeScript (inference is structural, and the compile still emits) — the complete lesson with code blocks and transcript corrections.


039 — Arrays in TypeScript (b6ryReBr0uw, ~10:58)

ProAcademy lecture on arrays as typed collections, and really on inference: ["John", 28, "male", 1000] infers (string | number)[], which accepts a pushed number but rejects a pushed boolean (“argument of type boolean is not assignable to parameter of type, string, or number”). Single-type arrays infer cleanly (string[], number[]); explicit forms (names: string[], (string | number)[] with the union pipe, a module-04 preview) write the same constraints by hand. Index access and for...of close it, with honest JavaScript behavior: out-of-range access yields undefined, not an error.

Screenshot refs: frame_00001.png (VS Code arrays lecture beside the course slide); frame_00002.png blank (annotation and error demos are code-only).

Full narrative: 039 — Arrays in TypeScript (inference from the initializer, enforced on every push) — the complete lesson with code blocks and transcript corrections.


061 — The satisfies Keyword (Xm_VGeTpS2Q, ~11:24)

satisfies checks a value against a general type without widening it to that type: annotating A: ObjectType erases the specific (value: string becomes string | number), while A satisfies ObjectType keeps the narrow type yet still rejects misspelled keys and wrong value types. Three uses follow: extracted ComplexOptions objects that keep autocomplete and per-key narrowness; Record<PrimaryColor, RGB> color maps that catch bad literals yet preserve specific values; and the signature pattern — a default clause ending in grade satisfies never, turning unhandled switch cases into compile errors so every future union addition fails loudly. Refrain: type safety as a refactoring tool.

Screenshot refs: frame-0001.jpg (404 page) through frame-0012.jpg (course slides) — presenter, logo, and blank frames with Pick/Partial/ReadonlyArray course slides interleaved.

Full narrative: 061 — This Amazing TypeScript Feature Has NO Docs!


110 — Advanced TypeScript Challenges (dyiVsjLTFv0, ~29:39)

Web Dev Simplified solves three type-challenges live against Expect<Equal<...>> cases: an easy MyExclude (“the core of almost every single advanced TypeScript thing you write” — naked-T distribution mapping excluded members to never), a medium KebabCase (double-infer head-plus-rest splitting, the Lowercase dash fix, the look-at-Rest leading-dash fix, and a tail-recursion wrapper that “absolutely blew my mind”), and a hard lodash-style Get (keyof fast path first for dotted literal keys, then dot-splitting with recursive descent — arrays come free since numeric indices are keyof the array). Closes on his i18n library’s ParseOptionType as production proof. The payoff for 060’s ladder under test pressure, and the deferred tier of 112’s syllabus.

type MyExclude<T, U> = T extends U ? never : T;
type T2 = KebabCase<"FooBarBaz">; // "foo-bar-baz"
type T3 = Get<Data, "foo.bar.count">; // number

Screenshot refs: frame-0001.png (leaderboard) through frame-0008.png (i18n end-card) — rig, distribution, infer split, kebab solve, tail recursion, Get, arrays, payoff.

Full narrative: 110 — Advanced TypeScript Challenges (Exclude, KebabCase, Get) — the complete lesson with all 8 screenshots, code blocks, and transcript corrections.


121 — Utility Types, Blazing Fast (EU0TB_8KHpY, ~03:08)

Matt Pocock speed-runs one file with no imports — “a set of types that are available globally in all TypeScript projects.” Three families in three minutes: object shapers (Partial for update payloads, Required, Omit/Pick plus their compositions, Readonly with a hand-rolled Mutable inverse), union operators (Exclude dropping members, Extract pulling one member out of the RoleAttributes discriminated union), and function/async extractors (ReturnType/Parameters for unexported library contracts, NonNullable, Awaited unwrapping Promise). Closes on the composed challenge Awaited<ReturnType<typeof asyncFunk>>. Pairs with 119 (union operators shrink constrained type parameters) and 114 (Partial meets exactOptionalPropertyTypes).

type Resolved = Awaited<ReturnType<typeof asyncFunk>>; // number
const n: Resolved = 42; // unwrapped, not Promise<number>

Screenshot refs: frame-0001.png (objects) through frame-0003.png (async close) — shapers, unions, extractors.

Full narrative: 121 — Utility Types, Blazing Fast (object shapers, union operators, extractors) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.

↑ contents


059 — You are a Junior Dev if You Don’t Know These 18 TypeScript Utility Types (BhNSauna0eo, ~22:09, Web Dev Simplified)

The video works through all 18 utility types against one base User type (id, name, age, address), motivated by three functions that each want a different slice of it: createUser wants everything except id, updateUser wants any subset, and renderUserDetails wants only name and age. Pick and Omit carve out exact subsets; Partial and Required flip optionality; Readonly

Full narrative: 059 — You are a Junior Dev if You Don’t Know These 18 TypeScript Utility Types (utility-type survey)


060 — Learn Advanced TypeScript In 25 Minutes (infer, extends, ternaries) (bnTAOB3P6nM, ~25:54, Web Dev Simplified)

The video climbs four rungs: extends means superset in every context — Dog extends Animal, interface B extends A, T extends string as a generic constraint (“at least a string”), and T extends string ? true : false as a compile-time if. infer adds extraction: T extends unknown[] ? infer A captures the element type into a new variable, which rebuilds ReturnType and Awaited from

Full narrative: 060 — Learn Advanced TypeScript In 25 Minutes (infer, extends, ternaries) (infer, extends, ternaries)


062 — This Is One Of My Favorite TypeScript Features (xsfdypZCLQ8, ~05:21, Web Dev Simplified)

The video argues that a single flat state type with optional fields actively fights you: a location state with optional coordinates and optional errorMessage lets impossible combinations through (loading with coordinates, success without them) and forces null checks everywhere. The fix is a discriminating union — split the one type into a LoadingLocationState, a SuccessLocationState, a

Full narrative: 062 — This Is One Of My Favorite TypeScript Features (discriminated unions)


module 04 — functions and generics

Narratives: 008 · 086 · 010 · 088 · 018 · 096 · 031 · 119 · 049 · 050 · 052


008 — The Function Type in TypeScript (jXoSaX_yFh4, 8:14)

How function types are inferred and declared: a variable holding a function infers a function type, or declare it ahead with the capitalized Function type (let greet: Function;). Typed parameters ((a: number, b: number)), optional (c?: number | string), and default (c: number | string = 10) parameters; required-first ordering rule. Return-type inference vs explicit annotation (: number); void (no value at all) vs undefined (a real value held by omitted optionals). Screenshot refs: frame 6 @ 0:04:31.9 and frame 10 @ 0:07:49.7 — src > sandboxes > x > add editor views (let greet: Function;, const add = (a: number, b: number, c: number | string = 18): number => {...}, calls add(5, 10); / add(5, 10, '20');).

Full narrative: 008 — The Function Type in TypeScript (params, defaults, void)


086 — The Function Type, Expanded Edition (jXoSaX_yFh4, ~8:16)

Expanded edition of the function-types lesson, from the bootcamp transcript pass. A variable holding a function infers a function type; declare it ahead with the capitalized Function (“function does use a capital”). Typed params (a: number, b: number), optional (c?: number | string — “all I have to do is place a question mark in front of it, and notice, when I do that, the error down here goes away”) versus default (= 10 — one or the other, required-first ordering), with undefined-vs-10 demoed in the browser. Return types inferred (hover result: number) then annotated (: number); void is no value at all, distinct from undefined.

Screenshot refs: frame-0001.png (inferred greet) through frame-0008.png (full file) — Function annotation, optional and default params, minus and result, void.

Full narrative: 086 — The Function Type (inference, Function, params, defaults, void) — the complete lesson with all 8 screenshots, code blocks, and transcript corrections.


010 — Function Signatures (TZNbzyY6hMU, ~7:45)

A function signature pins down exactly which functions a variable may hold: (params) => returnType. let greet: (a: string, b: string) => void; (param names are positional, not nominal — a/b vs name/greeting); let calc: (a: number, b: number, c: string) => number; (every code path must return a number — the missing-else error and fix); let logDetails: (obj: { name: string, age: number }) => void; (object-shape parameter), composed with a type alias (type Person = { name: string, age: number }). Screenshot refs: frames/frame-01.jpg (00:38, loose let greet: Function; setup) through frames/frame-06.jpg (07:06, full file with calc + logDetails during the type-alias close).

Full narrative: 010 — Function Signatures (pinning down params and return type)


088 — Function Signatures, Expanded Edition (TZNbzyY6hMU, ~7:45)

Expanded edition of the signatures lesson, from the bootcamp transcript pass. A signature pins the contract before the body: () => void, then three examples — greet: (a: string, b: string) => void (names positional, not nominal: “these can be called whatever you want, X and Y, if you prefer”), calc: (a: number, b: number, c: string) => number (the missing-else error and fix — every path must return), logDetails: (obj: { name: string, age: number }) => void composed with type Person. Lesson 8’s Function admits any function; signatures admit exactly one shape.

Screenshot refs: frame-0001.png (loose setup) through frame-0008.png (full file with the Person alias) — greet, calc error and fix, logDetails, hover detail.

Full narrative: 088 — Function Signatures (pinning params and return type before implementation) — the complete lesson with all 8 screenshots, code blocks, and transcript corrections.


018 — Generics (IOzkOXSz9gE, ~9:43)

The one idea: generics capture the type so reuse does not lose it. addUID(obj: object) returns the right runtime object ({ name, age, uid }) but the compiler forgets the input properties, so docOne.name errors. Declaring <T>(obj: T) captures the call-site type and carries it into the return type, restoring .name and .age access. Bare <T> accepts anything (addUID('hello') compiles), so extends sets the floor: <T extends object> rejects non-objects, and <T extends { name: string }> demands a string name while T still captures everything above the minimum.

Second half moves generics to interfaces: Resource<T> fixes uid: number and resourceName: string while data: T varies — Resource<string> ('shaun'), Resource<object> ({ name: 'shaun' }), Resource<string[]> (shopping list) — each with positive and negative cases, so one interface stays reusable without collapsing data to any.

Screenshot refs: frames embedded in the combined transcript (IOzkOXSz9gE-combined.md) — 00:48 addUID source + console, 02:25 property error, 04:03 extends constraint, 05:40 Resource reveal, 07:17 object-vs-string comparison, 08:54 shopping-list array.

Full narrative: 018 — Generics (generic functions, constraints, and Resource)


096 — Generics, Expanded Edition (IOzkOXSz9gE, ~09:44)

Expanded edition of the generics lesson, from the bootcamp transcript pass. addUID(obj: object) returns the right runtime object but the compiler forgets the input properties (docOne.name errors); <T>(obj: T) captures the call-site type (“placing angle brackets and then a big T in front of the function”) and restores access. Bare <T> accepts anything (addUID('hello') compiles), so extends sets the floor — <T extends { name: string }> demands a string name while T still captures everything above it. Then generics move to interfaces: Resource<T> with data: T instantiated as string, object, and string array.

Screenshot refs: frame-0001.png (untyped addUID) through frame-0010.png (object and array instantiations) — property error, <T> capture, extends floor, three Resource<T> uses.

Full narrative: 096 — Generics (addUID capture, extends constraints, and Resource) — the complete lesson with all 10 screenshots, code blocks, and transcript corrections.


031 — Learn TypeScript Generics in 13 Minutes (EcCTIExsqmI, ~12:51)

Web Dev Simplified’s compressed generics arc — the only video in this batch that teaches TypeScript itself, and a direct complement to 018. Every feature is motivated by a concrete failure of the simpler alternative first. The sequence: getFirstElement(arr: number[]) only accepts numbers; any[] erases the return to any (“obviously not very useful”); a union parameter widens the return to string | number even when the input is provably one side. The rule that falls out: whenever a function holds data whose type should track what was passed in, that is the perfect case for a generic.

function getFirstElement<ElementType>(arr: ElementType[]): ElementType {
	return arr[0];
}
const n = getFirstElement([1, 2, 3]); // number — inferred

Stdlib sightings prove generics are already in learners’ code: new Map<string, number>(), array.map inferring its return type, document.querySelector<HTMLInputElement>(...). Generic types follow the same arc via ApiResponse<TData> (call sites supply the argument explicitly — types cannot infer), narrowed with readability aliases (UserResponse, BlogResponse). Closes with defaults (<TData = { status: number }>), constraints (TData extends object), and the calibration that 90% of real usage is one unconstrained parameter with inference supplying the argument. Takeaway, verbatim: when data could be multiple types across uses but must stay the same type within a single use, use a generic.

Screenshot refs: both captioned frames are talking-head (non-technical); all code evidence comes from the narrated editor sessions in the full narrative.

Full narrative: 031 — Learn TypeScript Generics in 13 Minutes (same type within, any type across) — the complete lesson with both screenshots, code blocks, and transcript corrections.


119 — When Should I Use a Generic? (lMfGp29Ht8c, ~02:16)

Matt Pocock’s two-minute decision rule, live-coded in one file: “are all the elements known when I make the function?” A union parameter plus in-narrowing covers the case where every member is known up front; the generic arrives only when the function must remember which member it received — <TItem extends Animal | Human> with a conditional return type that yields animalName for animals and humanName for humans. Inside the body the narrowing needs casts, so the rule cuts both ways: same return for every input means the union version is the correct code and the generic is over-engineering. Pairs with 121 (Exclude/Extract operate on such constrained unions) and 123 (the rule scaled to architecture).

const getDisplayName2 = <TItem extends Animal | Human>(
	item: TItem,
): TItem extends Human ? { humanName: string } : { animalName: string } => {
	if ("name" in item) return { animalName: item.name } as never;
	return { humanName: `${(item as Human).firstName} ${(item as Human).lastName}` } as never;
};

Screenshot refs: frame-0001.png (union before) and frame-0002.png (generic after) — squiggle, conditional return.

Full narrative: 119 — When Should I Use a Generic? (one decision rule, conditional return) — the complete lesson with both screenshots, code blocks, and transcript corrections.

↑ contents


049 — #15 Function as Type | TypeScript Basics & Data Types | A Complete TypeScript Course (__iXrj3jKZs, ~11:51, procademy)

The lecture closes the basics arc by typing a variable as a function. It starts from JavaScript reality: let greet = greetUser works, but the inferred any type also permits greet = 100, and the resulting greet() call fails only at runtime (“greet is not a function”) with no compile-time complaint. Step one of the fix — let greet: Function — restores a compile error on the number assignme

Full narrative: 049 — #15 Function as Type | TypeScript Basics & Data Types | A Complete TypeScript Course (typing function values)


050 — #16 Function Type for Callback | TypeScript Basics & Data Types | A Complete TypeScript Course (bU7_gcBCEc8, ~07:41, procademy)

The lecture extends function types from the previous lesson to callbacks: a function parameter that is itself meant to receive a function. It opens with a recap — an addNumbers variable typed to accept (n1: number, n2: number) => number takes the sum function but rejects the add function, whose return type is void — then builds the callback case from scratch. A `getResult(num1, num2, pri

Full narrative: 050 — #16 Function Type for Callback | TypeScript Basics & Data Types | A Complete TypeScript Course (callback signatures)


052 — #18 Never Type in TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (k1LW7VjTF1U, ~09:25, procademy)

The lecture introduces never: a return type meaning the function will not return anything, ever — not even undefined. Setting never on the ordinary greetUser function errors (“a function returning never cannot have a reachable end point”) because it can fall off the end; setting it on createError(message: string, code: number), which throws an error object instead of returning, compile

Full narrative: 052 — #18 Never Type in TypeScript | TypeScript Basics & Data Types | A Complete TypeScript Course (exhaustive-check type)


module 05 — objects and interfaces

Narratives: 012 · 090 · 013 · 091 · 014 · 092 · 015 · 093 · 016 · 094 · 017 · 095 · 124 · 126


012 — Classes (OsFwOzr3_sE, ~7 min)

First classes lesson, taught in the Finance Logger project. Defines an Invoice class with three typed properties (client: string, details: string, amount: number), a constructor that assigns each parameter via this.*, and a format() method returning a sentence (${client} owes £${amount} for ${details}). Two instances (invOne for mario, invTwo for luigi) are logged to the console and rendered as list items in the app.

class Invoice {
	client: string;
	details: string;
	amount: number;

	constructor(c: string, d: string, a: number) {
		this.client = c;
		this.details = d;
		this.amount = a;
	}

	format(): string {
		return `${this.client} owes £${this.amount} for ${this.details}`;
	}
}

const invOne = new Invoice("mario", "work on the mario website", 250);
const invTwo = new Invoice("luigi", "work on the luigi website", 300);

Screenshot refs: OsFwOzr3_sE_frame_002.png (class definition with both instances), OsFwOzr3_sE_frame_006.png (format() method in src > apps.ts), OsFwOzr3_sE_frame_001/003/005.png (Finance Logger form + invoice list + console output).

Full narrative: 012 — Classes (blueprint, constructor, instances, format)


090 — Classes, Expanded Edition (OsFwOzr3_sE, ~08:46)

Expanded edition of the first classes lesson, from the bootcamp transcript pass. The Invoice data model end to end: three typed properties (client: string, details: string, amount: number), constructor assignment via this.* (“whenever we create a new invoice object we can pass in 3 different values”), the format() sentence (“this format method is only gonna return a string”), two instances via new (mario 250, luigi 300), an Invoice[]-only array, and the public-by-default sting in the tail — every property readable and writable, which lesson 13 takes away.

Screenshot refs: frame-0001.png (class with typed properties) through frame-0009.png (direct property reassignment) — constructor, format, instances, console, typed array.

Full narrative: 090 — Classes (Invoice properties, constructor, format, typed arrays) — the complete lesson with all 9 screenshots, code blocks, and transcript corrections.


013 — Classes: public, private, readonly (aYmnwDlPB8s, ~6:05)

Second classes lesson: access control on the Invoice class from 012. No modifier means public (readable and writable everywhere — the default). private details restricts access to inside the class body: direct inv.details reads error, but format() keeps working because it uses this.details internally. readonly client stays readable everywhere but cannot be reassigned anywhere — not on the instance, not even via this. inside the class (constructor assignment is the one exception).

modifierread outsidechange outsideread/write inside
public (default)yesyesyes
privatenonoyes
readonlyyesnoread-only (no reassignment, even inside)

Closes with the constructor parameter-property shorthand professional code uses: prefixing a parameter with a modifier auto-creates and assigns the property, so constructor(readonly client: string, private details: string, public amount: number) {} replaces the field declarations plus manual this.x = x lines (bare parameters without a modifier do not become properties). Output verified identical after the refactor (mario £250, luigi £300).

Screenshot refs: frames/aYmnwDlPB8s/frame_0002.png (starting class + instances + forEach loop), frame_0004.png (private details, direct access removed), frame_0006.png (readonly discussion), frame_0007.png (identical console output after shorthand refactor).

Full narrative: 013 — Access Modifiers (public, private, readonly, shorthand)


091 — Public, Private & Readonly, Expanded Edition (aYmnwDlPB8s, ~06:05)

Expanded edition of the access-control lesson, from the bootcamp transcript pass. Three modifiers on the Invoice class: unmarked means public (“All properties are public by default”), private details errors outside reads while format() keeps working through this, and readonly client stays readable but unchangeable everywhere except constructor initialization. Closes with the parameter-property shorthand — constructor(readonly client: string, private details: string, public amount: number) {} replacing declarations plus manual assignments — with output verified identical (mario £250, luigi £300).

Screenshot refs: frame-0001.png (explicit public starting class) through frame-0006.png (identical console after refactor) — private lockout, readonly freeze, shorthand.

Full narrative: 091 — Public, Private & Readonly (access control and the constructor shorthand) — the complete lesson with all 6 screenshots, code blocks, and transcript corrections.


014 — Modules (EpOPR03z4Vw, ~6:37)

First refactor lesson: until now all code lived in one file (src/app.ts); larger projects stay readable when split into modular files. Moves the Invoice class into its own module (src/classes/Invoice.ts), exports it (export class Invoice), and imports it back (import { Invoice } from './classes/Invoice.js';). Three setup steps: tsconfig.json gets "module": "ES2015" (keeps import/export in the compiled output) with "target": "ES6", index.html marks the entry script (<script type="module" src="app.js">), and only the class definition moves — instantiation (new Invoice(...)) stays in app.ts.

Key gotcha: write the .js extension in the import specifier even though the source is .ts — the browser loads the compiled JavaScript, and tsc preserves the specifier verbatim. Verify: the Finance Logger list (mario £250, luigi £300) renders identically; the refactor changed organization, not behavior. Two honest drawbacks: modern browsers only (TypeScript does not shim modules for old browsers), and each module is its own HTTP request — webpack previewed as the future fix. Next lesson: interfaces.

Screenshot refs: frames/frame_0001.png (motivating ReferenceError: Invoice is not defined), frame_0002.png (Invoice.ts open in editor), frame_0006.png (import line plus src/ tree), frames/frame_0005.png/frame_0007.png (identical transaction list + console after refactor).

Full narrative: 014 — Modules (export, import, and the .js specifier)


092 — Modules, Expanded Edition (EpOPR03z4Vw, ~06:37)

Expanded edition of the refactor lesson, from the bootcamp transcript pass. The Invoice class moves to src/classes/Invoice.ts with export in front; app.ts imports it back (import { Invoice } from './classes/Invoice.js') — with the .js extension even though the source is .ts, because the browser loads the compiled output and tsc preserves the specifier verbatim. Setup: "module": "ES2015" plus "target": "ES6" in tsconfig.json, <script type="module"> in index.html. Verified identical rendering (mario £250, luigi £300); two honest drawbacks (modern browsers only, one HTTP request per module) with webpack previewed as the fix.

Screenshot refs: frame-0001.png (single-file app before the split) through frame-0007.png (final state of both files) — tsconfig, export, import line, identical console and list.

Full narrative: 092 — Modules (export Invoice, import it back, mind the .js extension) — the complete lesson with all 7 screenshots, code blocks, and transcript corrections.


015 — Interfaces (VbW6vWTaHOY, 7:18)

The one idea: an interface enforces structure — it never creates objects. interface IsPerson declares the contract (name: string, age: number, speak(a: string): void, spend(a: number): number); annotating const me: IsPerson then requires every member with matching types, and the error clears only once all four are present. Interfaces are TypeScript-only — no interface keyword exists in JavaScript.

interface IsPerson {
	name: string;
	age: number;
	speak(a: string): void;
	spend(a: number): number;
}

const me: IsPerson = {
	name: "shaun",
	age: 30,
	speak(text: string): void {
		console.log(text);
	},
	spend(amount: number): number {
		console.log("I spent", amount);
		return amount;
	},
};

const greetPerson = (person: IsPerson) => {
	console.log("hello", person.name);
};

Three enforcement rules shown on screen: no missing members (empty initializer errors until all four land), no extras (adding skills: [] fails the excess property check), and parameter names are positional, not nominal (a in the interface vs text/amount in the object is fine — types, count, and return types must match). The payoff: any number of objects can share one contract with different values and method bodies, and greetPerson(person: IsPerson) gets IntelliSense (person. offers name, age, speak, spend) plus call-site checks (bare { name: '...' } rejected, me accepted, prints hello shaun). A class is a blueprint plus a constructor that creates objects; an interface is a contract only — no constructor, no instantiation, no runtime code emitted. Next lesson preview: classes declaring they implement an interface.

Screenshot refs: frame 2 @ 2:44 (IPerson spelling of the declaration), frame 4 @ 6:23 (IsPerson spelling plus greetPerson(me) and console.log(me)); frames 1 and 3 show the Finance Logger page as background context only.

Full narrative: 015 — Interfaces (contracts that enforce object shape)


093 — Interfaces, Expanded Edition (VbW6vWTaHOY, ~07:18)

Expanded edition of the interfaces lesson, from the bootcamp transcript pass. The contract, not the thing: interface IsPerson declares name, age, speak(a: string): void, spend(a: number): number — TypeScript-only, evaporating at compile time. const me: IsPerson must supply every member (names positional, not nominal: text for a is fine) and nothing extra (skills: [] fails the excess-property check). The payoff generalizes: many objects, one contract with different values, and greetPerson(person: IsPerson) moving the shape check to the call site.

Screenshot refs: frame-0001.png (IsPerson declaration) through frame-0007.png (greetPerson with the interface parameter) — annotation, excess-property error, second object.

Full narrative: 093 — Interfaces (IsPerson contracts on objects and function parameters) — the complete lesson with all 7 screenshots, code blocks, and transcript corrections.


016 — Interfaces with Classes (XPGFqx8Vg-Y, 11:08)

The payoff lesson for 015: interfaces stop describing plain objects and start constraining classes. The one idea — a class that declares implements HasFormatter must supply every member the interface demands, and in return any instance of that class is assignable anywhere the interface type is expected. Two different classes, one shared contract, enforced by the compiler.

the HasFormatter contract

A new folder (src/interfaces/) holds a new module (HasFormatter.ts) exporting a single-method interface. No properties — just the guarantee that anything implementing it can format itself as a string.

export interface HasFormatter {
	format(): string;
}

Screenshot refs: XPGFqx8Vg-Y_frame_001.png (new interfaces/ folder and HasFormatter.ts) through XPGFqx8Vg-Y_frame_002.png (finished interface declaration).

classes implement the interface

The existing Invoice class adopts the contract with the implements keyword, importing the interface the same way 014 imported classes — with the .js extension in the specifier even though the source is .ts, because the browser loads the compiled output.

import { HasFormatter } from "../interfaces/HasFormatter.js";

export class Invoice implements HasFormatter {
	constructor(
		readonly client: string,
		private details: string,
		public amount: number,
	) {}

	format(): string {
		return `${this.client} owes £${this.amount} for ${this.details}`;
	}
}

The check is structural: Invoice already has a format(): string method, so it passes with no changes. Delete or mis-type format and the compiler errors — the class no longer satisfies the contract. That is the whole enforcement mechanism: implements turns a convention (“remember to add format”) into a compile-time rule.

A second class proves the contract is shareable. Payment is copied from Invoice into src/classes/Payment.ts with one semantic change — client becomes recipient, and the sentence flips direction:

export class Payment implements HasFormatter {
	constructor(
		readonly recipient: string,
		private details: string,
		public amount: number,
	) {}

	format(): string {
		return `${this.recipient} is owed £${this.amount} for ${this.details}`;
	}
}

Two classes, different shapes (client vs recipient), same format(): string guarantee. Screenshot refs: XPGFqx8Vg-Y_frame_003.png (implements HasFormatter on Invoice) through XPGFqx8Vg-Y_frame_004.png (Payment.ts created).

the interface as a type

Once classes implement the interface, the interface name itself becomes a usable type — a variable, parameter, or array element typed HasFormatter accepts an instance of any class that implements it.

import { Invoice } from "./classes/Invoice.js";
import { Payment } from "./classes/Payment.js";
import { HasFormatter } from "./interfaces/HasFormatter.js";

let docOne: HasFormatter;
let docTwo: HasFormatter;

docOne = new Invoice("yoshi", "web work", 250);
docTwo = new Payment("mario", "plumbing work", 200);

let docs: HasFormatter[] = [];
docs.push(docOne); // ok — Invoice implements HasFormatter
docs.push(docTwo); // ok — Payment implements HasFormatter

The array version is the real win: docs accepts objects from unrelated classes, and every element is guaranteed to have format(): string — so a loop over docs can call .format() with no checks and no casts.

// console output after pushing both docs:
[Invoice { client: 'yoshi', ... }, Payment { recipient: 'mario', ... }]

Screenshot refs: XPGFqx8Vg-Y_frame_005.png (three imports in app.ts) through XPGFqx8Vg-Y_frame_008.png (docs array logged to the console with both objects).

putting it to work in the form handler

The demo variables are deleted and the pattern moves into the real submit handler from 011. One HasFormatter-typed variable replaces the separate invoice/payment paths: read the <select> value, construct the matching class, store it in doc.

let doc: HasFormatter;

if (type.value === "invoice") {
	doc = new Invoice(toFrom.value, details.value, amount.valueAsNumber);
} else {
	doc = new Payment(toFrom.value, details.value, amount.valueAsNumber);
}

console.log(doc);

Verified live: submitting “payment to yoshi, marketing, £100” logs a Payment object; submitting “invoice to mario, website work, £200” logs an Invoice. Either branch satisfies doc’s type because both classes implement the contract — the handler no longer cares which class it built, only that the result can format itself. Next lesson preview: a class that takes these objects and renders them to the screen (the list template).

Screenshot refs: XPGFqx8Vg-Y_frame_009.png (submit handler with the if/else construction) through XPGFqx8Vg-Y_frame_011.png (Finance Logger page with submitted payment and invoice entries).

Three rules to carry forward: implements is a compile-time check only (no runtime code emitted, same as interfaces in 015); interface-typed positions accept any implementing instance regardless of class; and a shared method guarantee (format(): string) is what makes heterogeneous collections like HasFormatter[] safe to iterate.

Full narrative: 016 — Interfaces with Classes (implements HasFormatter)


094 — Interfaces with Classes, Expanded Edition (XPGFqx8Vg-Y, ~11:08)

Expanded edition of the interfaces-with-classes lesson, from the bootcamp transcript pass. A new src/interfaces/ folder holds export interface HasFormatter { format(): string; } — “anything which implements or uses this interface should have” that method. Invoice adopts it via implements (structural check: its existing format() passes unchanged), then Payment proves the contract shareable (recipient instead of client, sentence flipped). The interface becomes a type: docOne/docTwo from different classes (“this variable must be of type has formatter”), a HasFormatter[] array holding both, and the submit handler’s single doc branch — verified live with a yoshi payment (£100) and a mario invoice (£200).

Screenshot refs: frame-0001.png (interfaces folder) through frame-0011.png (submitted entries on the page) — interface, implements, Payment, typed variables, docs array, handler.

Full narrative: 094 — Interfaces with Classes (HasFormatter, implements, and the form handler) — the complete lesson with all 11 screenshots, code blocks, and transcript corrections.


017 — Rendering an HTML Template (X-mUYxLjqLY, ~10:09)

Closes the loop from 016: the Finance Logger form built Invoice/Payment objects but only logged them to the console. Now a new ListTemplate class turns a formatted object into an li inside the page’s ul. Two jobs: register the list container in the constructor, expose a render method that builds the item template and inserts it at the start or end.

import { HasFormatter } from "../interfaces/HasFormatter.js";

export class ListTemplate {
	constructor(private container: HTMLUListElement) {}

	render(item: HasFormatter, heading: string, pos: "start" | "end") {
		const li = document.createElement("li");

		const h4 = document.createElement("h4");
		h4.innerText = heading;
		li.append(h4);

		const p = document.createElement("p");
		p.innerText = item.format();
		li.append(p);

		if (pos === "start") {
			this.container.prepend(li);
		} else {
			this.container.append(li);
		}
	}
}

Three module-05 patterns in one class: the constructor parameter property (private container: HTMLUListElement) registers the ul with no field declaration; render takes item: HasFormatter so either class qualifies and item.format() is guaranteed; pos: 'start' | 'end' is a literal union — only those two strings compile. Plain DOM API (createElement, innerText, append/prepend) with types inferred from the tag string (li hovers as HTMLLIElement, no annotations).

Wiring in app.ts: grab the single ul (querySelector('ul')! — the ! because querySelector can return null), construct one ListTemplate, and in the submit handler build a HasFormatter-typed doc (invoice or payment branch) then list.render(doc, type.value, 'end'). Old console.log lines deleted. Payoff: submitting an invoice for Mario appends <li><h4>Invoice</h4><p>mario owes £250 for website work</p></li> — the format() string moves from console to page.

Screenshot refs: frame 1 (0:00:38, plan-as-comments) · frame 2 (0:01:54, Finance Logger form) · frame 3 (0:03:10, finished class — use over mid-edit frame 7 @ 0:08:15) · frame 4 (0:04:26, console “before” state) · frame 5 (0:05:42, app.ts wiring) · frame 8 (0:09:31, rendered list item). Note: transcript “URL” always means ul.

Full narrative: 017 — Rendering an HTML Template (ListTemplate class)


095 — Rendering an HTML Template, Expanded Edition (X-mUYxLjqLY, ~10:09)

Expanded edition of the list-template lesson, from the bootcamp transcript pass. The class is sketched as comments first, then built: constructor(private container: HTMLUListElement) registers the ul via parameter property, and render(item: HasFormatter, heading: string, pos: 'start' | 'end') takes either class through the interface (“it’s not gonna be invoice cos it could be a payment as well”) — “This is just regular JavaScript right here” for the createElement/innerText/append body, with a literal-union pos choosing prepend vs append. Wiring: querySelector('ul')!, one ListTemplate, list.render(doc, type.value, 'end') in the handler — the format() string moves from console to page.

Screenshot refs: frame-0001.png (plan-as-comments) through frame-0010.png (rendered list item) — shell, signature, template body, wiring, browser payoff.

Full narrative: 095 — Rendering an HTML Template (ListTemplate render with HasFormatter items) — the complete lesson with all 10 screenshots, code blocks, and transcript corrections.


124 — Object Oriented TypeScript #1, Introduction (HsWKyERYGKQ, ~10:17)

j4orz motivates classes with a running Alice-versus-Bob Mario-clone story: Alice’s move(characterNum) and playSound(characterNum) dispatch on a character number, Bob binds move() and playSound() into one class per character. The spec changes — Peach arrives with a WAV voice file and flight — and Alice re-opens tested code with if/else branches while Bob adds one class. Four parallel classes duplicate everything, so the shared methods factor up into a Player superclass (“we only have to maintain one class”), with Peach overriding both methods back down. Closes in oop.ts with the knows-versus-does split (health/velocity/position versus move/crouch/attack) and the first live const mario = new Player(). The theory pass for 126; pairs with 125 (same hardcoded-to-declared arc for props) and 128 (the extends twin of the Player factoring).

class Player {
	move(): void {
		/* make the character move */
	}
	playSound(): void {
		/* play this character's voice file */
	}
}
class Peach extends Player {
	move(): void {
		/* peach specific: fly */
	}
	playSound(): void {
		/* peach specific: play .wav */
	}
}

Screenshot refs: frame-0001.png (title card) through frame-0007.png (live instantiation) — procedures, change cost, superclass, overriding, blueprint, editor.

Full narrative: 124 — Object Oriented TypeScript #1 (procedures vs classes, inheritance, first object) — the complete lesson with all 7 screenshots, code blocks, and transcript corrections.


126 — OOPS in TypeScript, Class and Object (Y6nURzENB2A, ~29:17)

Way2Future’s Hinglish drill pass for 124’s theory: Greeter anatomy slide (class, field, constructor, method), a UML Circle box (attributes versus operations), then live coding in class.ts on an edit-tsc-refresh loop — class student { name: string; rollNo: number; }, const elon = new student(), a sayHello() method reading this.name and this.rollNo, then steve and mark joining as second and third instances with independent state. Closes on the seven-row object-versus-class table (instance versus blueprint, physical versus logical, new versus class). Frames carry the code where the auto-transcript mangles it. Pairs with 125 (typed-fields-first in both) and 127 (explicit annotations as strict-mode discipline).

class student {
	name: string;
	rollNo: number;
	sayHello(): void {
		console.log("student name " + this.name + ", roll no is " + this.rollNo);
	}
}
const elon = new student();
elon.name = "elonMusk";
elon.rollNo = 20;
elon.sayHello();

Screenshot refs: frame-0001.png (desktop open) through frame-0008.png (contrast table) — Greeter, Circle, fields, instantiation, method, three instances.

Full narrative: 126 — OOPS in TypeScript (Greeter anatomy to three instances) — the complete lesson with all 8 screenshots, code blocks, and transcript corrections.

↑ contents


module 06 — patterns and best practices

Narratives: 071 · 074 · 075 · 116 · 122 · 123 · 127 · 128 · 129 · 130 · 131 · 132 · 133 · 134 · 136 · 137 · 138 · 139 · 140 · 141 · 142 · 143 · 144 · 145 · 067

Module 06 collects the cross-cutting surveys: one video that runs the whole language end to end, so patterns (guards, generics, utility types) land in relation to each other rather than in isolation.


071 — TypeScript Crash Course with RoadsideCoder (DTR2p7D6tjk, ~40:39)

A single-file crash course from zero to advanced in 40 minutes: global install, tsc --init config tour (rootDir/outDir, module, target, strict — “if you made it false, then there’s no point of using TypeScript”), then primitives, tuples, enums, any vs unknown (“unknown is generally considered safer than any”), typed functions with optional/default/rest params, interfaces with optional/readonly/methods, the type-vs-interface rule (“interfaces are generally preferred for object shapes and types for unions or intersections”), unions/intersections/literals, as assertions with typeof/instanceof guards, classes with modifiers and parameter-property shorthand plus extends/super, generics with constraints, six utility types worked on one Todo (Partial/Required/Readonly/Pick/Omit/Record plus ReturnType), numeric/string/const enums, and typed Promise<T>/async returns. The through-line: “TypeScript is built on top of JavaScript and it helps us catch so many errors before they hit the production”.

Screenshot refs: frame-0002.jpg (config walkthrough) through frame-0008.jpg (utility-type demos) — talking-head and blurred-editor shots, no code-slide OCR.

Full narrative: 071 — TypeScript Crash Course (beginner to advanced in 40 minutes) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.


074 — Zod Schema Validation with WDS (9UVPk0Ulm6U, ~07:13)

Zod pitched as the TypeScript-first validation library: required-by-default fields (.optional() to opt out), immutable zero-dependency schemas, npm install zod plus the z object, parse (returns or throws) vs safeParse ({ success, data, error } — right for forms), and the centerpiece z.infer<typeof Schema> so the shape is declared once and the static type derived (“you don’t have to define your types twice”). Chainable refinements (min/max/length, custom messages), literals, and object combinators (pick/omit/keyof/extend), proved by a before/after demo where a wall of if/else form checks collapses into a 5-line formSchema — “it works exactly the same” and changing a rule is a one-token edit.

Screenshot refs: frame-0001.jpg (docs-page opening) through frame-0003.jpg (docs table of contents) — talking-head plus docs slides.

Full narrative: 074 — Zod Schema Validation (parse, safeParse, z.infer) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.


075 — Zod Docs Walkthrough, Extended Edition (L6BE-U3oy80, ~31:02)

A ~31-minute screen-led tour of the zod.dev docs (visual skeleton — the audio transcript failed upstream, so no quotes are cited): Introduction through Numbers table of contents (~1.4M/week downloads, Chinese-translation note — a newer docs snapshot than the 074 video), separate install paths for npm (Node/Bun) and deno.land/x (Deno) plus strict-mode requirements, then a primitive-by-primitive pass in docs order (literals, strings, coercion, datetime, numbers). For worked code, pair with the 074 companion — same headline concept (one schema yields runtime validation plus the static type via inference) with a complete transcript.

Screenshot refs: frame-0001.jpg (tour opening) through frame-0003.jpg (docs table of contents) — talking-head, interstitial, and docs slides.

Full narrative: 075 — Zod Docs Walkthrough (install, primitives, coercion) — the visual skeleton with all 3 screenshots (no transcript; worked code lives in 074).


116 — TypeScript Anti-Patterns (f5ibYFCBGXA, ~14:16)

Devowski’s senior code-review patter over numbered title cards — seven mistakes from “many successful teams, projects, and products,” each paired with its fix: “I bet my life at least one of them applies to 90% of the programmers, even more senior ones.” Stringly-typed domains narrowed to unions, early-return guards plus is ValidStatus predicates restoring narrowing the includes call cannot, Record<ValidStatus, string> annotated before the literal so the editor scaffolds keys, boolean-soup states counted by Cartesian product and restated as one discriminated union (the cautionary twin of 115’s Block renderer), honest naming (no I prefixes, no Data suffixes, singular types, descriptive generics), bottom-up atoms-first design (117 in miniature), and the DeepPartial close that turns advanced-TypeScript fear into vocabulary — the on-ramp to 110. The annotate-first demand is the code twin of the hygiene tier in 114.

const messages: Record<ValidStatus, string> = {
	pending: "waiting",
	inProgress: "running",
	rejected: "refused",
}; // missing key errors here, not in a far-away consumer

Screenshot refs: frame-0001.png (string-primitive card) through frame-0003.png (utility-type gymnastics) — sin, soup, vocabulary.

Full narrative: 116 — TypeScript Anti-Patterns (seven sins, seven fixes) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.


122 — Design Patterns Intro (wAX8VA7FH8M, ~01:30)

Simply Explained’s ninety-second series thesis, straight to camera with no code on screen: “many problems in programming have already been solved by others and don’t require you to solve them again.” Three reasons to adopt patterns — no re-solving, extendability-designed quality, and the team vocabulary that turns code review into pattern matching — plus the episode lineup (decorator, strategy, observer, facade, adapter) as the forward index. Prerequisite: basic object-oriented programming and TypeScript. The pointer file for the pattern episodes, paid off immediately by 123.

const seriesLineup = ["decorator", "strategy", "observer", "facade", "adapter"] as const;
type Pattern = (typeof seriesLineup)[number]; // "decorator" | "strategy" | "observer" | "facade" | "adapter"

Screenshot refs: frame-0001.png (open) and frame-0002.png (lineup close) — all-talk episode, code blocks illustrate the spoken thesis.

Full narrative: 122 — Design Patterns Intro (thesis, payoffs, series lineup) — the complete lesson with both screenshots, code blocks, and transcript corrections.


123 — Factory Patterns (-1YhP5IOBCI, ~22:06)

Jack Herrington builds three creational patterns twice each — class variant first, functional rewrite second, every one verified with a ts-node run — in the episode-1-factories project: abstract factory hides the production-or-dev logger decision behind one NODE_ENV-reading call, builder injects an IFileReader into a generic DirectoryScraper so reuse flows both ways, factory method fuses the seam with an abstract class (then with a closure-returning createDirectoryScraper). The shared moral: loosen the coupling between the code that decides an object should be created and the code that creates it. The payoff of 122’s thesis, the 119 rule at architecture scale, contracts built from 121’s machinery.

const createDirectoryScraper =
	(reader: IFileReader) =>
	(dirPath: string): Record<string, unknown> =>
		directoryScraper(dirPath, reader);

Screenshot refs: frame-0001.png (studio open) through frame-0006.png (studio close) — logger, refactor, reader, transition, wrap.

Full narrative: 123 — Factory Patterns (abstract factory, builder, factory method, twice each) — the complete lesson with all 6 screenshots, code blocks, and transcript corrections.


127 — Code Review, TypeScript Fundamentals (TuH9HrgIFks, ~04:12)

Nexiform’s sketch-explainer review checklist in four pillars: any misuse is active sabotage (“turning off your smoke detectors just because you burnt toast once”) enforced by ESLint rather than eyeballs; missing types are passive negligence fixed config-level with strict plus noImplicitAny; every as assertion is a red flag to replace with type guards or runtime schemas; interface design is the constructive half — “do these interfaces actually accurately model the domain?” The closing robustness test: good design removes the temptation to cheat the type system at all. Compresses 125 (pillar 2 caught live as ts(7006)) and 128 (all four pillars demoed in an editor) to checklist form; pillar 4 names what the Player extraction in 124 practices.

// robust design needs no escape hatches
type CheckState = "InProgress" | "Success" | "Fail"; // nothing to assert, nothing to any
declare function checkState(s: CheckState): void;
checkState("Success"); // compiles; other strings do not

Screenshot refs: frame-0001.png (shield thesis) through frame-0004.png (blueprint close) — checklist, title card, four bullets, constructive close.

Full narrative: 127 — Code Review Fundamentals (any, missing types, assertions, interfaces) — the complete lesson with all 4 screenshots, code blocks, and transcript corrections.


128 — TypeScript Mistakes Every Junior Developer Should Avoid (ZCllX1p763U, ~13:39)

CoderOne’s five-mistake bad-versus-good tour through a clean-typescript project: unknown over any (“I don’t know what the type is, but I will know when I use it”), is predicates over boolean checks plus as casts (petIsCat narrows, the boolean twin forces (p as Cat)), satisfies over widening annotations (goodUser.image. keeps the narrowed type while staying contract-checked), string unions over numeric enums (BadState accepts 100, GoodState rejects garbage), and derived Partial/Omit/Record over hand-rolled optionality. The editor demo of 127’s checklist; upgrades the 125 annotation style with satisfies, warns against the 120 numeric defaults, and enters 121’s utility catalog.

const goodUser = {
	id: 1,
	firstName: "Alex",
	lastName: "Brooks",
	image: "image-url",
} satisfies IUser;
goodUser.image.toUpperCase(); // inferred string, still contract-checked

function updateProduct(id: number, updates: Omit<Partial<IProduct>, "id">): void {
	/* patch any subset of fields except id */
}

Screenshot refs: frame-0001.png (npm stake) through frame-0008.png (utility close) — unknown, guards, is-operator, satisfies setup and payoff, enums, utilities.

Full narrative: 128 — Junior Mistakes, Clean Code (unknown, is, satisfies, unions, utilities) — the complete lesson with all 8 screenshots, code blocks, and transcript corrections.


129 — How To Reduce Code Review Time (f9Vqz_jSrbc, ~00:46)

Developer Timeline’s 46-second satirical short, staged as a movie-clip trading-floor pitch under the lower-third “IT’S THE NEW WAY OF TESTING IN THE AI ERA”: oversized PRs get waved through because “the larger the PR gets, the faster it gets approved” (reviewer fatigue, not tooling), then the escalation — “we generate the code, merge it as fast as possible, and let production tell us what works” — “we eliminate QA costs and cut code review time by 98%” with “nearly tripled” productivity because verification was deleted, not improved. The cautionary opener for the batch arc: 130 orders the skipped checks first, 131 is the 65-item procedure it deletes, 132 red-proofs the discarded test stage, and 133 prices real QA at seven minutes.

// the satirized gate: size observed, rigor not
function review(pr: { filesChanged: number }): { approved: boolean } {
	const tooLargeToRead = pr.filesChanged > 50;
	return { approved: true }; // waved through either way
}

Screenshot refs: frame-0001.png (trading-floor cut with the AI-era caption) — single-frame short, code blocks reconstruct the spoken claims.

Full narrative: 129 — How To Reduce Code Review Time (satire: rubber stamps and customer-led QA) — the complete lesson with the screenshot, code blocks, and transcript corrections.


130 — The Ultimate Code Review Checklist (07UTtCf7sCA, ~02:34)

Codegrip’s music-only visual walkthrough — no narrator, zero speech items across two transcription passes, the text overlays carry the lesson over office-desk stock and minified-code b-roll. Two theses: order the checklist by technical-debt contribution (“you must do checks that are more essential before those that do not contribute significantly to technical debt” — completeness is not the goal, sequencing is), and the quality definition quoted whole (“A good quality code has low technical debt and requires the least help in future development and manipulations”). Answers 129’s premise directly and states the ordering principle 131 applies across 65 items; the named debt is concrete in 132’s signature-change story.

// essential-first ordering (frame 1 overlay)
type Check = { name: string; debtWeight: number };
const checks: Check[] = [
	{ name: "naming", debtWeight: 1 },
	{ name: "missing error handling", debtWeight: 9 },
	{ name: "formatting", debtWeight: 2 },
];
checks.sort((a, b) => b.debtWeight - a.debtWeight);

Screenshot refs: frame-0001.png (essential-first overlay) and frame-0002.png (quality definition) — the 2 captioned frames (a third, a black end card, carries no content).

Full narrative: 130 — The Ultimate Code Review Checklist (visual walkthrough: debt-first order, quality defined) — the complete lesson with both screenshots, code blocks, and transcript corrections.


131 — Code Review Checklist (CXfBWdSvF8g, ~15:49)

Tomer Ben David’s 65-item document walkthrough, one static numbered list slow-scrolled top to bottom with a red highlight parking per item — “in this episode I’m just scanning everything.” Observability first (hot paths silent, single-shot paths traced; alerts on aggregations, not single errors), then the change surface (“a coding task is not only the feature” — scale, reporting, UX, deploy verification as code), requirements skepticism (“is this solving the real problem”, future needs to the backlog or “we are taking like a loan”), state traps (immutability over mutation, shared state handled with care, cache invalidation), control-flow smells (“prefer positive logic”, 3-argument rethink, ~150-char lines), component testing with decoupled failures (“bulk test fail smell”), right-sized types with open-closed APIs, one global failure catcher plus an explicit step-1-2-3 main flow, and the craft close (“the most important thing is the naming of stuff”, squash for one-step revert, “time to understand” as itself the defect). The procedure 129 skips; worked hands-on by 132 and entered in seven minutes by 133.

// items 52 and 56: one global failure boundary plus a legible main flow
async function step1(): Promise<string> {
	return "loaded";
}
async function step2(s: string): Promise<string> {
	return `${s}+checked`;
}
async function step3(s: string): Promise<void> {
	console.log(`done: ${s}`);
}
async function main(): Promise<void> {
	await step3(await step2(await step1()));
}
main().catch((e) => console.error("global boundary:", e));

Screenshot refs: frame-0001.png (list top) through frame-0011.png (requirements close) — 11 sampled frames in scroll order (source frames 1, 2, 3, 4, 7, 8, 9, 11, 12, 15, 16).

Full narrative: 131 — Code Review Checklist (65 items: observability, requirements, smells, testing, craft) — the complete lesson with all 11 screenshots, code blocks, and transcript corrections.


132 — TypeScript Fundamentals #13, Jest Testing (l6C-nRG83pQ, ~14:53)

Code With Blake hangs the whole video off one story — toCentimeter(feet, inches) gaining a leading parameter while every existing call site silently breaks (“we’ve effectively just broken our function, and anywhere this function is used is now also broken”) — then builds the apparatus that would have caught it: jest, @types/jest, ts-jest (297 packages) with preset: 'ts-jest' plus testMatch: ['**/*.test.ts'], describe/test/expect anatomy to the first green run, the deliberate red proof (2.54 becomes 2.55, expected 190.5 received 191.25), a boundary second case plus jest --watchAll (“we didn’t break it enough to break all of the test cases, we just broke certain test cases”), parameterization into a testCases array where a new test is one entry (3 ft 5 in maps to 104.14), jest-html-reporter output read in a browser (manually refreshed), and the comparison-matcher close for floats. Full-length pass over 133; implements 131’s testing item; answers 129 with evidence.

// data-driven cases: new test equals one array entry
const testCases = [
	{ input: { feet: 6, inches: 3 }, expected: 190.5 },
	{ input: { feet: 0, inches: 0 }, expected: 0 },
	{ input: { feet: 3, inches: 5 }, expected: 104.14 },
];

Screenshot refs: frame-0001.png (project open) through frame-0009.png (matcher autocomplete) — 9 sampled frames in order (source frames 1, 2, 3, 6, 8, 9, 11, 12, 15).

Full narrative: 132 — TypeScript Fundamentals #13, Jest Testing (toolchain, red proof, watch mode, reporter) — the complete lesson with all 9 screenshots, code blocks, and transcript corrections.


133 — Jest TypeScript Basics (S5fQNEAod_s, ~06:55)

26 Brains’ seven-minute quick start in WebStorm from a literally empty folder: npm init, TypeScript plus tsc --init (tsconfig left untouched), npm install jest (266 packages, “properly” devDependencies), then thinking aloud through each error — the describe skeleton fails with TS2582 until npm i @types/jest (“our little problem there has kind of gone away”), the placeholder expect(1+1).toEqual(2) proves the harness before any code exists, typed code breaks the run (“jest isn’t really designed to work with TypeScript”) until npm i ts-jest plus npx ts-jest config:init writes the transform, the adder extracts into app.ts across a module boundary, and "test": "jest" banks the suite with exit code 0. Minimal compliant instance of 131’s testing item, short path to 132, and the price tag under 129’s pitch: deleting QA saves seven minutes and bills production instead.

// app.ts — the extracted unit
export const adder = (a: number, b: number): number => a + b;

Screenshot refs: frame-0001.png (fresh project) through frame-0007.png (wired green suite) — all 7 frames in order.

Full narrative: 133 — Jest TypeScript Basics (scaffold, TS2582, ts-jest, first green test) — the complete lesson with all 7 screenshots, code blocks, and transcript corrections.


134 — Mocking React Components and Functions using Jest (kCe1DDFy09I, ~26:11)

Bruno Antunes’ deliberate escalation from one pinned random number to a suite where every heavyweight is a stub — “we will start from a very simple example with just functions, and then we will make it a little bit harder”. jest.spyOn(Math, "random") plus mockReturnValue pins randomBetween per boundary (0 gives 3, 0.5 gives 4, 0.999999 gives 5); mockClear() per beforeEach cures the accumulating counter (“we tell the spy to forget the past and just start to count from now”); jest.fn() replaces the done-callback style for the onMoney(33) prop; jest.mock factories with jest.requireActual spread stub the MUI DataGrid and SwipeableDrawer while keeping siblings real; mocked() from ts-jest/utils types the stubs; loose objectContaining prop assertions plus the {} React context argument close the props test; and an adjacent __mocks__/VeryComplex.tsx stubs the shared heavyweight — 5 suites, 9 tests, all green, with HTTP mocking refused by design (“avoid using mocking to mock your HTTP calls”, deferred to MSW).

// partial module mock — everything real except the trusted heavyweight
jest.mock("@material-ui/data-grid", () => ({
	...jest.requireActual("@material-ui/data-grid"),
	DataGrid: jest.fn(() => <div>Table</div>),
}));

Screenshot refs: frame-0001.png (pinned random) through frame-0011.png (SIMPLE VERSION, full suite green) — 11 sampled frames in order (source frames 1, 4, 5, 7, 10, 12, 14, 17, 20, 22, 26).

Full narrative: 134 — Jest Mocking for React (spyOn, jest.fn, module factories, manual mocks) — the complete lesson with all 11 screenshots, code blocks, and transcript corrections.


136 — Unit Testing, Vitest Mock Functions (uX5SF94RBNI, ~12:10)

The Net Ninja’s Vitest spelling of 134’s beats: deal floods the console because logDealRound fires once per round and the logger “isn’t critical to the rest of the code”, so vi.mock("../src/helpers/loggers") auto-mocks the module (37 of 37 stay green, logs gone), the factory form registers custom bodies, and await vi.importActual(path) spread keeps unmocked siblings working (“will essentially be undefined if it’s not registered” otherwise). Mocking buys observability — “if we didn’t mock this function, then we wouldn’t be able to use this assertion, because we can’t monitor functions by default” — and the count assertion fails first at 17 calls against 5 expected because the file-level counter “doesn’t reset then for every single test case”, cured by logDealRound.mockClear(): 38 of 38 green, closing on toHaveReturnedWith(true) return stubbing.

// partial mock — real siblings, stubbed logger
vi.mock("../src/helpers/loggers", async () => {
	const originals = await vi.importActual("../src/helpers/loggers");
	return { ...originals, logDealRound: vi.fn(() => true) };
});

Screenshot refs: frame-0001.png (noisy deal) through frame-0008.png (return stub, 38 of 38) — 8 sampled frames in order (source frames 1, 4, 5, 6, 9, 10, 11, 12).

Full narrative: 136 — Vitest Mock Functions (vi.mock, importActual, call counts, mockClear) — the complete lesson with all 8 screenshots, code blocks, and transcript corrections.


137 — Playwright Jest Config and Launch Browser (DbdqflN3dJ4, ~12:01)

LetCode with Koushik’s browser-scale end of the testing arc: the part-1 toolchain (jest ^26.6.3, ts-jest ^26.5.0, playwright ^1.8.0) drives a four-await chain — chromium.launch(), browser.newContext(), context.newPage(), page.goto("https://letcode.in") — each stored in const “because there is no way to change this one”, with page.goto “exactly like your browser.get or the driver.get in selenium or in Protractor”. Config is two files: tsconfig (target: es6, strict: true, module: commonjs, sourceMap: true) plus the package.json jest block (preset: ts-jest, testEnvironment: node, full moduleFileExtensions) — “by default, whatever the code we are going to write, everything should be async and await”. The first run fails on Jest’s default “Exceeded timeout of 5000 ms” because the browser “just keeps on running” headless; await browser.close() plus headless: false for a visible run closes it.

// the full chain — four awaits, all const
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
await page.goto("https://letcode.in");
await browser.close();

Screenshot refs: frame-0001.png (toolchain) through frame-0007.png (close fix) — 7 sampled frames in order (source frames 1, 3, 6, 8, 9, 10, 11).

Full narrative: 137 — Playwright Jest Config and Launch Browser (toolchain, async chain, timeout fix) — the complete lesson with all 7 screenshots, code blocks, and transcript corrections.


138 — Jest Tutorial, Unit Testing in JavaScript (diC9TvwXSUM, ~06:49)

camelCase’s brisk prequel to the whole testing run: npm install jest --save-dev (“because we only need it as a dev dependency and not in our production code”), "test": "jest" wiring, and the first test("adds 1 + 2 to equal 3") passing in 0.125 s — then the lesson that matters, “not just to feed a function with valid data, but also to try to enter invalid data”: expect(sum(1, "hello")).toBeUndefined() fails on "1hello", and TDD red-green-refactor adds only the typeof guard (“it should only solve the problem”). Test Explorer click-to-run plus auto-run mirrors 132’s watch mode; describe grouping plus Istanbul coverage (an untested diff drops statements to 80 percent, functions to 50) mirrors its reporter. The video states its definition of useful tests: the one that feeds the function something wrong.

// minimal green — the guard only
function sum(a, b) {
	if (typeof a !== "number" || typeof b !== "number") return undefined;
	return a + b;
}

Screenshot refs: frame-0001.png (sum typed) through frame-0005.png (coverage report) — 5 sampled frames in order (source frames 1, 3, 4, 6, 7); both talking-head frames carry no code and are excluded.

Full narrative: 138 — Jest Unit Testing Starter (first test, TDD red-green, coverage) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


139 — Introduction To Testing In JavaScript With Jest (FgnxcUQ5vho, ~13:56)

Web Dev Simplified’s testing-module entry and the long-form twin of 138: Jest as a devDependency with "test": "jest" wiring, the test plus expect anatomy over a sum fixture, then the matcher the starter never reaches — toEqual for deep equality, taught through a cloneArray case where toBe identity fails on “received serializes to the same string”. Closes with npm test -- --coverage reporting across four tested functions (sum, subtract, cloneArray, plus coverage), the map-not-grade role Istanbul plays in 138.

// cloneArray.test.js — deep equality, not identity
import { cloneArray } from "./cloneArray";

test("properly clones array", () => {
	const array = [1, 2, 3];
	expect(cloneArray(array)).toEqual([1, 2, 3]);
});

Screenshot refs: frame-0001.png (title card) through frame-0005.png (coverage report) — 5 sampled frames in order (source frames 1, 3, 5, 9, 11).

Full narrative: 139 — Introduction to Testing in JavaScript with Jest (install, first test, coverage) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


140 — Why Vitest Is Better Than Jest (7f-71kYhK00, ~13:13)

Kyle replays 139’s sum fixture under Vitest to price the Jest-era setup: “VTest has all the amazing features of Jest built into it, but it’s created for a modern approach to JavaScript, and it has TypeScript support out of the box, import, export support, and you really don’t have to do any configuration at all.” The scaffold (npm create plus a period) ships TypeScript and Vite with watch mode green in about a second; the rest-parameter sum suite passes under plain ESM imports; one coverage.reporter key in vite.config.ts climbs to 100 percent; and import.meta.vitest guards colocate tests inside sum.ts while stripping them from production builds.

// sum.ts — test colocated, stripped from production builds
import { describe, it, expect } from "vitest";

if (import.meta.vitest) {
	describe("sum", () => {
		it("returns sum with multiple numbers", () => {
			expect(sum(1, 2, 3)).toBe(6);
		});
	});
}

Screenshot refs: frame-0001.png (tsconfig plus dev server) through frame-0005.png (Vitest suite green) — 5 sampled frames in order (source frames 2, 5, 7, 8, 9); the opening talking-head frame carries no code and is excluded.

Full narrative: 140 — Why Vitest Is Better Than Jest (TypeScript support, ESM, coverage, inline tests) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


141 — Unit Testing (Vitest) Tutorial #1 - What is Unit Testing? (XdDZKeM5_pQ, ~10:40)

The Net Ninja’s vocabulary lesson: “A unit test is just a small piece of code that tests a specific function or module in your application” with the one non-negotiable property — “it should be isolated from the rest of the application”. Slide deck interrogates applyDiscount three ways (correct discount for valid codes, none for invalid), the isolation diagram draws input-to-unit-to-output with nothing else participating, then the vitest_unit_testing scaffold (vitest ^4.0.3, "test": "vitest") banks the vocabulary in a runnable project.

{
	"name": "vitest_unit_testing",
	"version": "1.0.0",
	"scripts": {
		"test": "vitest"
	},
	"devDependencies": {
		"vitest": "^4.0.3"
	}
}

Screenshot refs: frame-0001.png (error-case tests) through frame-0005.png (wired devDependency) — 5 sampled frames in order (source frames 1, 4, 5, 8, 10).

Full narrative: 141 — What Is Unit Testing (Vitest tutorial 1, isolation, scaffold) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


142 — Unit Testing (Vitest) Tutorial #7 - Test Driven Development (9VVCUhcV2gA, ~24:13)

The series centerpiece spends 141’s vocabulary on a full red-green build: “the tests are driving the development of the code.” The createCards suite is written first as specification (array shape, exactly 52 cards, non-array rejection, non-standard-length rejection, { value, suit } shape, real combinations, duplicate refusal), then the implementation earns green with three guard tiers — TypeError for non-arrays, RangeError for wrong lengths, Set-size duplicate detection — around the nested suit-by-value loop. “You think about edge cases, bad import errors, and all of that stuff right from the start” is the dividend: documentation, modularity, and a safety net.

export function createCards(suits, values) {
	if (!Array.isArray(suits) || !Array.isArray(values)) {
		throw new TypeError("suits and values must be arrays");
	}

	if (suits.length !== 4 || values.length !== 13) {
		throw new RangeError("suits and values must be standard lengths four and 13");
	}

	if (new Set(suits).size !== suits.length || new Set(values).size !== values.length) {
		throw new Error("suit array contains duplicates" || "value array contains duplicates");
	}

	const cards = [];
	for (const suit of suits) {
		for (const value of values) {
			cards.push({ value, suit });
		}
	}

	return cards;
}

Screenshot refs: frame-0001.png (TDD comments) through frame-0005.png (guarded implementation) — 5 sampled frames in order (source frames 1, 6, 12, 18, 24).

Full narrative: 142 — Test-Driven Development with Vitest (createCards, 52-card deck, guards) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


143 — Vitest Simplified (snCLQmINqCU, ~04:54)

LearnVue’s five-minute bridge from functions to components: Vitest rides Vite so the “2 PIPELINES TO KEEP TRACK OF” title card dissolves into one transform stack serving dev and test. npm install -D vitest plus test.globals buys bare test/expect calls; the first example asserts a plain object (“we’ll just say Matt is 22”) before any framework enters; then @vue/test-utils mounts HelloWorld with a message prop — “pass it props, and then check what our props equal” — the mount-and-assert beat 144 replays in React spelling.

// vitest.config.js — globals on, imports optional
import { defineConfig } from "vitest/config";

export default defineConfig({
	test: {
		globals: true,
	},
});

Screenshot refs: frame-0001.png (two-pipelines card) through frame-0004.png (component click test) — 4 sampled frames in order (source frames 1, 2, 4, 5).

Full narrative: 143 — Vitest Simplified (Vite-native setup, globals, Vue components) — the complete lesson with all 4 screenshots, code blocks, and transcript corrections.


144 — React Vite Testing Tutorial For Beginners - Vitest Testing Crash Course (CxSL0knFxAs, ~38:31)

PedroTech’s four-beat component suite from a boilerplate Vite plus React app: Greeting renders default and named text via getByText; the Counter beat adds userEvent clicks found by role; UserProfile stubs global.fetch with a vi.fn resolving a canned user (“Now how are we going to test this because if you think about it this component uses a” network) — the 136 partial-mock doctrine in React form; and renderHook plus act test useCounter below the DOM layer. Behavioral throughout: render what users see, click what they click, fake only the network.

import { vi, describe, it, expect } from "vitest";

describe("UserProfile", () => {
	it("fetches and displays the user data", async () => {
		global.fetch = vi.fn();
		const mockResponse = { id: 4, name: "John", email: "john@email.com" };
		global.fetch.mockResolvedValueOnce({
			ok: true,
			json: () => Promise.resolve(mockResponse),
		});
		render(<UserProfile />);
		expect(screen.getByText("John")).toBeInTheDocument();
	});
});

Screenshot refs: frame-0001.png (title card) through frame-0005.png (hook tests plus browser) — 5 sampled frames in order (source frames 1, 9, 17, 27, 36).

Full narrative: 144 — React Vite Testing Crash Course (greeting, counter, mocked fetch, hooks) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


145 — Vue Unit Testing #1 - Project setup (f8dkz1kbm7Q, ~03:40)

Igor Babko’s series opener spends its whole runtime on harness discipline: pin Vitest 2.0.4 across framework, UI, and coverage (“I’m going to use latest versions at the time of this recording, which is 2.0.4”), install the test-utils package (“a bunch of helpful utilities that are going to help us test view components”), then bank the green run — “all tests have passed” — plus the verification triple of dependencies, browser-openable app, and executable runner. The Vue-side standing start 144 assumes; the 136 mocking vocabulary is the next skill the harness exists to serve.

{
	"devDependencies": {
		"vtest-cover-hv8": "^2.0.4",
		"vtest-ui": "^2.0.4",
		"vtest-framework": "^2.0.4"
	}
}

Screenshot refs: frame-0001.png (workspace) through frame-0004.png (green run) — all 4 frames in order.

Full narrative: 145 — Vue Unit Testing 1, Project Setup (Vitest 2.0.4, test utils, first green) — the complete lesson with all 4 screenshots, code blocks, and transcript corrections.

↑ contents


067 — Is tRPC The End Of REST/GraphQL? (lxnPMB0Jc7E, ~13:47, Web Dev Simplified)

The video “Is tRPC The End Of REST/GraphQL?” explores the evolution of API development and introduces tRPC as a modern alternative to traditional REST and GraphQL approaches. It highlights the limitations of REST in ensuring type safety and the complexity of GraphQL’s query language. tRPC is presented as a solution that combines the simplicity of REST with the type safety and code generation benef

Full narrative: 067 — Is tRPC The End Of REST/GraphQL? (end of REST?)


module 07 — project application

Narratives: 011 · 089 · 021 · 063 · 069 · 125 · 072 · 073 · 076 · 077 · 078 · 107 · 108 · 057 · 058 · 064 · 065 · 066


011 — The DOM & Type Casting (hcuKd-Q_tP8, ~11:19)

DOM work in TypeScript is the same queries, listeners, and properties as JavaScript, plus strictness: document.querySelector returns a possibly-null union (HTMLAnchorElement | null), so reading .href off the raw result errors. Two fixes: a runtime if (anchor) check when existence is uncertain, or the non-null assertion (querySelector('a')!) when you control the HTML. Per-element types are the payoff — once narrowed, anchor. offers only anchor-valid members.

Tag selectors keep their type (querySelector('form')! is HTMLFormElement) but class selectors widen to generic Element; the remedy is an as cast (querySelector('.new-item-form') as HTMLFormElement, dropping the !). Each form field is queried by id and cast to its control type (#type to HTMLSelectElement, the three inputs to HTMLInputElement), then a submit listener with (e: Event) and e.preventDefault() reads .value from each. One catch: .value is always a string, so the numeric amount uses valueAsNumber (verified blue-number vs white-string in the console). Screenshot refs: Finance Logger app preview, app.ts anchor/form/cast editor views, submit-handler build, valueAsNumber console check (frames 1–19 in narrative).

Full narrative: 011 — The DOM & Type Casting (querySelector, null, and as casts)


089 — The DOM & Type Casting, Expanded Edition (hcuKd-Q_tP8, ~11:19)

Expanded edition of the DOM lesson, from the bootcamp transcript pass. Same queries as JavaScript, plus strictness: querySelector('a') infers HTMLAnchorElement | null (“TypeScript doesn’t actually know whether there is an anchor tag in the index page”) — fix with if (anchor) when uncertain, ! when you control the HTML. Tag queries keep their element type; class queries widen to Element and take an as cast ('.new-item-form' as HTMLFormElement, dropping the !). Each field is queried by id and cast to its control type (#type to HTMLSelectElement, three inputs to HTMLInputElement), then a submit listener with e.preventDefault() reads .value from each — strings throughout, so the amount needs valueAsNumber before the Invoice constructor.

Screenshot refs: frame-0001.png (project layout) through frame-0011.png (wired-form console) — null union, assertion, widening, cast, fields, submit handler.

Full narrative: 089 — The DOM & Type Casting (querySelector nullability, as casts, form values) — the complete lesson with all 11 screenshots, code blocks, and transcript corrections.


021 — Wrap Up (fPYbNXzXP6M, ~2:02)

Series closer, no new syntax. Recap of what the course covered: basic types, function types, type aliases, classes and interfaces, modules, the DOM, generics, enums, and tuples. Durable habit: reach for the official TypeScript docs first — explanations plus live runnable examples. Stated (not covered) next steps: TypeScript with Webpack for bundling browser assets, and Node.js with TypeScript for server-side work. Screenshot refs: frame 1 @ 0:24 (bundler landing page), frame 2 @ 0:49 (nodejs.org download page — 12.16.1 LTS / 13.11.0 Current as shown at recording time, now historical).

Full narrative: 021 — Wrap Up (course recap, docs-first habit, stated next steps)


063 — First TypeScript Project: Todo List (jBmrduvKl5w, ~28:29)

A beginner todo app in two acts. Act one is setup: npm init -y, TypeScript as a dev dependency, tsc --init, a src/ → dest/ split wired with outDir, and tsc --watch — then the moment plain tsc breaks down (CommonJS require output, no node_modules resolution in the browser) and a bundler (Snowpack blank-TypeScript template) takes over. Act two is the app: generic querySelector<HTMLUListElement>, as casts for getElementById, | null + optional chaining + control-flow narrowing, a Task type (id/title/completed/createdAt) with uuid + @types/uuid, a Task[] store with a checkbox change listener, and localStorage persistence where getItem’s string | null forces a null guard and JSON.parse’s any forces an explicit Task[] return.

Screenshot refs: frame-0001.jpg (blank canvas, Snowpack install) through frame-0003.jpg (editor/browser split, createElement inference) — one technical frame, two non-technical.

Full narrative: 063 — How To Build Your First TypeScript Project - TODO List Application


069 — React + TypeScript with PedroTech (665UnOGx3Pg, ~50:10)

The jobs-and-scale case for TypeScript in React (“I doubt that you’re going to be hired if you don’t know TypeScript … TypeScript is used in almost every single company”), then one Person/User example carried through every React surface: Vite scaffold, basic annotations with strict mode, .tsx-for-components (untyped props are implicit any), props interfaces that turn a silent string-age lie into a visible error (“the exact same thing” as PropTypes), fetch-shaped nulls that force error handling, explicit useState<boolean> generics with string | null unions for empty states, the two memorize-worthy handler types (React.ChangeEvent<HTMLInputElement>, React.FormEvent<HTMLFormElement>), a full CRUD UserContext (exported entity type, context type, createContext<T>, ReactNode children, provider-value enforcement), a Countries enum that rejects “Wakanda”, and a guided JavaScript-to-TypeScript migration of a UserProfileEditor (props → events → state, then read the library generics).

Screenshot refs: frame-0001.jpg (Vite setup) through frame-0007.jpg (enum/migration close) — mostly talking-head, code slides carry no OCR.

Full narrative: 069 — React + TypeScript (props, state, events, context) — the complete lesson with all 4 screenshots, code blocks, and transcript corrections.


125 — React TypeScript Tutorial 3, Typing Props (KpA6oEaCHtk, ~05:48)

Codevolution’s five-minute focused pass on the one React surface 069 surveys: a prop-less Greet rendering a hardcoded greeting becomes (props) — which errors immediately with ts(7006) implicit-any — then (props: GreetProps) with type GreetProps = { name: string }, and the squiggles clear in both files. Payback is instant: props. autocompletes name, and name={10} fails at the call site instead of in the browser. Convention note: type for applications, interface for libraries. The hardcoded-to-parameterized arc mirrors 124; the ts(7006) is the negligence 127 hunts, and the annotation style gets its satisfies upgrade in 128.

type GreetProps = {
	name: string;
};

export const Greet = (props: GreetProps) => {
	return (
		<div>
			<h2>Welcome {props.name}! You have 10 unread messages</h2>
		</div>
	);
};

Screenshot refs: frame-0001.png (hardcoded start) through frame-0005.png (annotated close) — squiggle, midpoint, call-site autocomplete, resolution.

Full narrative: 125 — Typing React Props (GreetProps contract) — the complete lesson with all 5 screenshots, code blocks, and transcript corrections.


072 — Typewriter Typing-Animation Library with WDS (gWD0EJgBlYQ, ~27:17)

Kyle rebuilds the third-party typewriter class behind his course landing page as a hand-rolled TypeScript library: five chainable methods (typeString, pauseFor, deleteChars, deleteAll, start) that all return this, a promise queue deferred until start() (each entry a QueueItem = () => Promise<void>, awaited in a for...of because forEach + await doesn’t serialize), an owned appended div animated per character with setInterval/clearInterval, one private addToQueue helper, innerText chosen over textContent because the latter is string | null, as HTMLDivElement for querySelector nullability, looping via shift + re-push inside a while (a for loop can’t track a changing list), and private fields plus F2 rename-symbol to close. “I’m sure there’s probably a better way to do this. And if you’re like a TypeScript guru, tell me because this seems kind of messy”.

Screenshot refs: frame-0006.jpg (queue intro) through frame-0018.jpg (loop re-push) — code-editor-with-facecam slides, no OCR.

Full narrative: 072 — Typewriter Library (queue, async, DOM types) — the complete lesson with all 8 screenshots, code blocks, and transcript corrections.


073 — Shopping Cart with React + TypeScript, WDS (lATafp15HWA, ~61:37)

A persistent multi-page shopping cart teaching large-project conventions: Vite + React Router + Bootstrap scaffold with six feature folders and named exports, items.json data rendered through a responsive grid with key={item.id}, a formatCurrency utility on Intl.NumberFormat, a typed context exposing exactly four cart functions (“adding an item to the cart is the exact same as increasing our cart quantity by 1”) plus open/close and derived reduce quantity, immutable find/map/filter updates with ?. ?? 0, an Offcanvas cart (with the live-caught show-not-open fix), CartItem rows with product-lookup guards, and a generic useLocalStorage<T> hook (lazy initializer, function-check cast, as tuple return) that survives refresh — “If I refresh my page, you can see we still have 2 books and 3 computers”. Styling-first, logic-second throughout.

Screenshot refs: frame-0006.jpg (store grid) through frame-0018.jpg (storage-hook cast fix) — cards, editors, and logo frames.

Full narrative: 073 — Shopping Cart (context, immutable updates, generic storage) — the complete lesson with all 9 screenshots, code blocks, and transcript corrections.


076 — Custom React Select from Scratch with WDS (bAJlYgeovlg, ~46:10)

A fully custom Select in React + TypeScript with Vite: single-select first, then multi-select on the same component, finished with keyboard accessibility (Enter/Space toggle-and-select, ArrowUp/ArrowDown highlight, Escape close). The TypeScript spine is a discriminated union — SingleSelectProps (multiple?: false, value: SelectOption | undefined) vs MultipleSelectProps (multiple: true, value: SelectOption[]) — so narrowing on multiple types each branch’s value/onChange for free. Along the way: Vite scaffold stripped to "Hi", CSS Modules (styles["clear-btn"] bracket access), em-scaled container with focus ring, selected-vs-highlighted list states (.highlighted after .selected), container-toggle/onBlur-close/stopPropagation discipline with a highlight-reset effect, dismissible multi badges, and a ref-gated keydown effect whose [isOpen, highlightedIndex, options] dependency array fixes the stale closure.

Screenshot refs: frame-0005.jpg (sponsor) through frame-0012.jpg (final import) — scaffold, overlay errors, and finished component.

Full narrative: 076 — Custom React Select (discriminated unions, keyboard access) — the complete lesson with all 7 screenshots, code blocks, and transcript corrections.


077 — React Notes App with TypeScript and React Router (j898RGRw0b4, ~74:08)

A ~74-minute note-taking app build (visual skeleton — the audio transcript failed upstream, so no quotes are cited): Highlight sponsor segment (error/session dashboard plus the highlight.run ErrorBoundary integration snippet), a typed addTag helper via functional immutable append, nested React Router routes (/ → NoteList, /new → form, /:id → detail) carrying typed props (availableTags, onSubmit, onAddTag), real debugging on camera (broken JSX → [plugin:vite:react-babel] Unexpected token overlay → fix), and a NoteCard component (Bootstrap Card as Link, SimplifiedNote props) iterated across three frames to its finished shape.

Screenshot refs: frame-0003.jpg (Highlight dashboard) through frame-0012.jpg (finished NoteCard) — dashboard, snippet, error entry, routes, and component iterations.

Full narrative: 077 — React Notes App (routes, NoteCard) — the visual skeleton with all 8 screenshots (no transcript).


078 — Multi-Step Form with a Reusable useMultistepForm Hook (uDCBSnWkuH0, ~28:22)

A three-step signup form (User Details → Address → Account Creation) whose step state lives in a reusable useMultistepForm(steps: ReactElement[]) hook returning step, index, bounds-guarded goTo/next/back, and first/last flags. The shell layers a step counter, conditional Back (type="button" — bare buttons submit) / Next-or-Finish buttons, and per-step native validation by advancing through the form’s onSubmit with preventDefault instead of onClick. Form data persists across steps in one FormData state object merged via updateFields(fields: Partial<FormData>), each step declaring slice types (UserData/AddressData/AccountData), inside a FormWrapper (ReactNode children) for consistent title-plus-grid layout — “our data is being persisted because now we’re storing it in state”.

Screenshot refs: frame-0001.jpg (hook build) through frame-0003.jpg (finished form) — talking-head, interstitial, and terminal-plus-form shots.

Full narrative: 078 — Multi-Step Form (Partial, ReactNode) — the complete lesson with all 3 screenshots, code blocks, and transcript corrections.


107 — YouTube Homepage Clone (ymGB1lqP1CM, ~1:49:07)

Web Dev Simplified rebuilds the YouTube homepage piece by piece against the real site in a side window: Tailwind secondary palette extension, a cva Button (VariantProps plus ComponentProps, merged with twMerge), header flex groups, CategoryPills translate state clamped against scrollWidth/clientWidth with ResizeObserver chevrons, an auto-fill video grid with Intl formatters (“CSS grid is amazing”), hover autoplay previews, dual sidebars with string-or-element icons, and a SidebarContext state machine with responsive toggle and resize cleanup. Applies 104’s default-to-type rule at project scale and 105’s narrowing inline; scales up to a full-stack store in 108.

export type ButtonProps = VariantProps<typeof buttonStyles> & ComponentProps<"button">;

Screenshot refs: frame-0001.png (reference split-screen) through frame-0008.png (sidebar context) — button variants, pills scroll, grid formatters, sidebar state.

Full narrative: 107 — YouTube Homepage Clone (Tailwind theme, cva Button, typed grid, sidebar state) — the complete lesson with all 8 screenshots, code blocks, and transcript corrections.


108 — Full-Stack Ecommerce Store (iqrgggs0Qk0, ~3:42:32)

Web Dev Simplified builds a digital-download storefront end to end — “literally every single thing you would need to get started with an e-commerce project”: create-next-app plus Prisma on SQLite with schema before screens, cents pricing with snapshotted orders, Cascade/Restrict delete rules as business policy, server-component aggregates, Zod field-error maps sharing one schema with the insert, useTransition pending UI, Basic-auth download routes, revalidatePath at every mutation redirect, an isolated Stripe CheckoutForm, entitlement-before-charge duplicate guards, Resend emails with hosted images, and enumeration-safe order history. Reuses 107’s grid-plus-card pattern and 106’s Intl instinct; hardens the Zod side next in 074–075.

if (existing != null) return { error: "You already own this product" };

Screenshot refs: frame-0001.png (schema plus dashboard) through frame-0010.png (order history) — aggregates, product form, Stripe keys, purchase guard, emails.

Full narrative: 108 — Full-Stack Ecommerce Store (Next.js, Prisma, Stripe, Tailwind) — the complete lesson with all 10 screenshots, code blocks, and transcript corrections.

↑ contents


057 — Introduction to React #1 | Deployment (j8AVXNozac8, ~11:34, Jack Herrington)

Episode one deliberately starts in reverse: deployment before code. After a prerequisites check (HTML tags, CSS formatting/grid, JS objects/arrays/functions), the presenter scaffolds a starting-react app with Create React App via npx, runs it with yarn start, pushes it to a new GitHub repo, then deploys it to GitHub Pages with the gh-pages package (homepage key plus predeploy/deploy

Full narrative: 057 — Introduction to React #1 | Deployment (deploy-first React intro)


058 — Introduction To React #2 | JSX (HwNArS3f1Ss, ~06:56, Jack Herrington)

Episode two builds the Pokemon Search app’s HTML using JSX, tripping over each gotcha in turn. The presenter strips App.js to a single div, adds an h1 and a centered .title class, then hits the first surprise: HTML class is className in JSX because the markup compiles to JavaScript. Inline styles are the second: a string of CSS becomes a double-braced JS object with camelCased numeric-

Full narrative: 058 — Introduction To React #2 | JSX (JSX essentials)


064 — This Is A Great Beginner React/TypeScript Project (-ONUyenGnWw, ~44:24, Web Dev Simplified)

A hangman game built with Vite React-TS across ~44 minutes: scaffold (npm create vite, React + TypeScript template, move files up, npm i), strip to an <h1>, then plan state first — wordToGuess (random from a word list) and guessedLetters: string[], with won/lost derived, not stored. Three components follow: HangmanDrawing (pure-CSS gallows + six body parts revealed via `BODY_PARTS.slic

Full narrative: 064 — This Is A Great Beginner React/TypeScript Project (React + TS starter)


065 — What Is TanStack Router And Why I Love It (OwoZtv6u9p4, ~09:37, Web Dev Simplified)

The video introduces TanStack Router, a type-safe routing solution for web applications, emphasizing its benefits over traditional routing systems. It highlights how TypeScript enhances type safety, autocomplete, and error detection in routing. TanStack Router provides a robust framework for defining, nesting, and managing routes with built-in support for search parameters, loaders, and error

Full narrative: 065 — What Is TanStack Router And Why I Love It (typesafe routing)


066 — How To Build A Chat App With React And Stream (Een66E0X_os, ~94:01, Web Dev Simplified)

The video “How To Build A Chat App With React And Stream” by Web Dev Simplified walks through the process of creating a real-time chat application using React for the frontend and Stream for the backend. The project is built with a client-server architecture, where React handles the UI and Fastify serves as the Node.js backend. TypeScript is used for type safety, and environment variables are mana

Full narrative: 066 — How To Build A Chat App With React And Stream (stream chat build)

full course 023 — Learn TypeScript Full Course (SpwzRDUQ1GI, ~2:06:12)

freeCodeCamp / Scrimba full course with instructor Bob Ziroll. One console project throughout (no HTML): a pizza restaurant with a menu array, a cashRegister number, an orderQueue array, and three functions (addNewPizza, placeOrder, completeOrder). Scrimba runs TypeScript in-browser; locally the same step is renaming index.js to index.ts with TypeScript as a dependency.

Transcription note: Whisper mistranscriptions corrected — “Bob Ziroll” (not “Bob’s role”), cashRegister (not “cash in the register”), orderQueue (not “order Q”), addNewPizza (not “ad new pizza”), “loosey-goosey typing”, Kent C. Dodds quote (“TypeScript will not make your life terrible, it will show you how terrible your life already is”).

chapters


023-01 the one idea

TypeScript is a superset of JavaScript: all valid JavaScript is valid TypeScript. It adds compile-time (and in modern IDEs, real-time as-you-type) checking that catches TypeErrors — the app-crushing runtime errors that otherwise surface only after deploy. Three reasons to learn it: confidence (fewer crashes reach users), productivity (typed autocomplete, refactoring, inline errors in VS Code), employability (table stakes at many companies). It does not fix logical errors — only type-shape errors. Analogies: a house blueprint and a stud guard (steel plate stopping a too-long screw from hitting lines) — small upfront work preventing catastrophe.


023-02 the project

const menu = [
	{ name: "Margherita", price: 8 },
	// ... 4 pizzas total
];
const cashRegister = 100; // BUG (seeded): must be let, reassigned on orders
const orderQueue = [];
let nextOrderId = 1; // BUG (seeded): declared const in the lesson, must be let

Challenges: (1) addNewPizza(pizzaObj) pushes a menu-shaped object; (2) placeOrder(pizzaName) finds the pizza with menu.find(), adds its price to the register, creates { id, pizza, status: "ordered" }, pushes to the queue, returns it; (3) completeOrder(orderId) finds the order by id, sets status to "completed", returns it. The id uses the nextOrderId++ post-increment trick. Seeded bugs (~00:13:28): const on reassigned variables, and calling completeOrder with a string id while ids are numbers.


023-03 red squigglies

Copying the JS into index.ts produces red squigglies with zero TypeScript-specific code written. Rule: hover every squiggly (Scrimba does not record the IntelliSense popup). Three free fixes: cashRegister/nextOrderId (const to let), and selectedPizza (“object is possibly undefined” — menu.find() may match nothing). The fix introduces the course’s central habit — happy path vs sad path:

const selectedPizza = menu.find((pizzaObj) => pizzaObj.name === pizzaName);
if (!selectedPizza) {
	console.error(`${pizzaName} does not exist in the menu`);
	return; // must stop execution so TS narrows the rest
}
cashRegister += selectedPizza.price;

Limit (~00:24:00): the string-vs-number completeOrder bug and the possibly-undefined order are NOT flagged yet — TS cannot help further until explicit types are defined.


023-04 basic types and inference

let myName: string = "Bob";
myName = 5; // ERROR: type 'number' is not assignable to type 'string'

Explicit : string here is busy work — TS derives the type from the assigned value. Reassigning a variable to a different data type is a code smell. Style note: in object types separators are free choice (commas, semicolons, nothing) — stay consistent per project.


023-05 custom object types

type Person = {
	name: string;
	age: number;
	isStudent: boolean;
};

Applied to the app: Pizza type { name: string; price: number }, then addNewPizza(pizzaObj: Pizza) surfaces the seeded bug — test calls pass cost instead of price (“object literal may only specify known properties”). Nested objects two ways: inline, or extracted (Address) when reused. Removing any required property errors — the “rigidity” new users feel is the point in production.


023-06 optional properties

type Person = {
	name: string;
	age: number;
	isStudent: boolean;
	address?: Address; // ? = may be omitted
};

One ? after the property name. Warning repeated through the course: every flexibility feature (optional, any, loose generics) trades away type safety — ask “do I really need this flexible?” first.


023-07 typed arrays and signatures

const menu: Pizza[] = [
	/* ... */
];
const orderQueue: Order[] = [];

function addNewPizza(pizzaObj: Pizza): void {
	/* ... */
}
function placeOrder(pizzaName: string): Order | undefined {
	/* ... */
}
function completeOrder(orderId: number): Order | undefined {
	/* ... */
}

This finally catches the seeded completeOrder("1") string-id call. Same pattern standalone with fetchUserDetails(username: string): User (~01:15:00): explicit return type : User stops a future refactor from silently returning user.username (a string). void for functions returning nothing; Order[] explains the earlier mystery — .find() on orderQueue can also return undefined.


023-08 literal types plus unions

type UserRole = "guest" | "member" | "admin";

type User = {
	username: string;
	role: UserRole;
};

Applied to orders (~01:02:00 challenge): status: "ordered" | "completed" instead of string. Inference subtlety: the newOrder object literal is inferred as { status: string }, which no longer satisfies the narrower Order type — annotate or construct it as an Order so the literal is checked, not widened.


023-09 type narrowing

Proving which union member you hold before operating on it: truthiness/falsy guards (if (!selectedPizza) return), === undefined checks, typeof guards. Takeaway quote from the recap (~02:04:54): narrowing code “is a great example of how TypeScript really helps you learn to think more like a senior developer” — edge-case thinking at write time.


023-10 any, unknown, return types

let value: any = 1;
value = "hello"; // no error — checking is OFF
value.nonExistentMethod(); // no error — any silences everything

any turns off checking: do not use it. One legitimate use is temporary scaffolding during JS-to-TS migration, with a warning that temporary anys are hard to remove later (better to leave warnings visible and relax strictness config instead).


023-11 utility types

type UpdatedUser = Partial<User>; // every property optional — update payloads
function updateUser(id: number, updates: UpdatedUser) {
	/* ... */
}

function addNewUser(newUser: Omit<User, "id">): User {
	const user: User = { id: nextUserId++, ...newUser };
	users.push(user);
	return user;
}

Partial fails for creation; Omit with a second type-argument (property name/names to remove) fits. Pizza-app mirror: addNewPizza(pizzaObj: Omit<Pizza, "id">) builds newPizza: Pizza with id: nextPizzaId++. Scrimba caveat (~01:47:30): the in-browser editor did not understand Omit at recording time, so the instructor demonstrates via VS Code screenshots. Docs pointer: TypeScript handbook utility-types page (Partial and Omit sections).


023-12 generics

function getLastItem<PlaceholderType>(array: PlaceholderType[]): PlaceholderType {
	return array[array.length - 1];
}
getLastItem([1, 2, 3]); // inferred PlaceholderType = number

Convention is <T>; the instructor starts with <Type>/<PlaceholderType>, then switches. Applied as generic addToArray<T>(array: T[], item: T): T[]. Payoff lesson (~01:59:00): addToArray(orderQueue, {..., status: "done"}) does NOT error — TS infers T as the widened object literal (status: string). Fix with an explicit type argument:

addToArray<Order>(orderQueue, { ... , status: "done" });
// ERROR: '"done"' is not assignable to '"ordered" | "completed"'

Mini-challenge answer: the blank in addToArray<___>(orderQueue, ...) is Order.


023-13 recap and scope

Closing recap (~02:04:21): basic + literal + custom types → optional properties → unions → narrowing → built-in utility types → generics. Stated scope: not exhaustive; planned follow-ups include TypeScript with the DOM. Learner advice: replay with hands on keyboard; use Google/ChatGPT with specific questions when stuck.


023 coverage map (modules 00-05)

modulecourse coveragenarrative section
00 start (env, js-to-ts)js pizza app, index.ts move, squigglies023-02, 023-03
01 why (safety net, tsc)confidence/productivity/employability, blueprint, sad path023-01, 023-03
02 basics (inference, any/unknown/never)inference, any, unknown, void023-04, 023-10
03 shapes (arrays, tuples, interfaces, optional/readonly)Person/Pizza/Address, optional, Pizza[]/Order[] (types-as-interfaces; tuples/readonly not covered)023-05, 023-06, 023-07
04 functions (signatures, unions, narrowing, guards)signatures, return types, unions, narrowing023-07, 023-08, 023-09
05 architecture (literals, enums, generics, utility)literals, UserRole enum-pattern, Partial/Omit, generics023-08, 023-11, 023-12
06 config (tsconfig strict, MCP)not covered (strict config mentioned only in passing re any)—
07 capstone (analyst agent)not covered—

Gaps (source from other itinerary videos): tuples, readonly, interfaces-vs-types, never, tsconfig strict, enums as a type.


023 screenshot refs

  • frame-0001.png (00:00:00) — “Why learn TypeScript?” slide (Confidence / Productivity / Employability)
  • frame-0010.png (00:11:01) — “CURRICULUM OVERVIEW” slide (fundamentals + why TypeScript is useful)
  • frame-0038.png (00:45:20) — two Person objects (Joe/Jill) with nested address in the editor
  • frame-0075.png (01:30:40) — “What does the Partial type do?” interstitial
  • frame-0084.png (01:41:41) — Omit-based addNewPizza in the editor with terminal output
  • frame-0103.png (~02:04:21) — “TypeScript Basics” recap slide (Type Annotations / Type Inference / Type Checking)

Full narrative: 023 — Learn TypeScript Full Course (pizza app, squigglies to generics) — the complete lesson with all 6 key screenshots, code blocks, coverage map, and transcript corrections.

↑ contents


full course 070 — Dave Gray TypeScript Full Course, 17 Lessons (gieEQFIfgYc, ~8:22 total)

“This video is made up of 17 tutorials that build upon each other much like the chapters of a book”: eleven vanilla-TypeScript lessons (setup with per-lesson folders and tsc -w, primitives through aliases, function alias-vs-interface advice — “I like to use the type aliases more than I do an interface” — assertions and DOM, classes, index signatures with key as keyof Student, generics, then utility types from Partial to Awaited), a two-lesson Vite arc (tooling intro, then a localStorage-persisted list project), four React-hooks lessons (Heading props two ways, effects with the React 18 strict-mode remount, useReducer, useContext), and a two-lesson Acme-widgets cart capstone reusing every hook — contexts + reducer + import.meta images + Intl pricing, then product/cart/line-item pages with a confirm flow, closing on memo + Object.keys/keyof comparators verified in React DevTools (“it should only render the cart line item that you change”). Sign-off: “Remember to keep striving for progress over perfection, and a little progress every day will go a very long way”.

Screenshot refs: frame-0001.jpg (title slide) through frame-0100.jpg (memo comparators) — title cards, docs page, editors, and split editor/browser shots.

Full narrative: 070 — Dave Gray TypeScript Course (basics to cart with memo) — the complete lesson with all 9 screenshots, chapter list, coverage map, and transcript corrections.

↑ contents


full course 099 — Learn TypeScript – Full Tutorial (30LWjhZzg50, ~4:46:24)

Hitesh Choudhry’s freeCodeCamp beginner-to-intermediate course: TypeScript as “JavaScript with type discipline” — “write better code in JavaScript, and that’s the whole idea of TypeScript.” Node check and first tsc compile, tsconfig strict as a dial, lowercase primitives, inference vs any, typed function params/returns, the signup/Card type-alias reshuffle, arrays/unions/RGB tuples, SeatChoice enums, interfaces, a User class (readonly, private, getters/setters), abstract classes, generics building to getPropertyValue<T, K extends keyof T>, and the dedicated detection.ts narrowing module (typeof/in/instanceof, predicates, exhaustive never switch over Circle | Square).

Transcription note: Whisper mistranscriptions corrected — “Hitesh”, tuples (not “twoples”), boolean (not “bullion”), if/else, TypeScript.

chapters


099-01 setup and the idea

Node install check, first tsc intro.ts compile in the terminal, and the tsconfig strict family as a dial. The framing never changes: types make JavaScript safer and more readable, not ceremony.


099-02 primitives, inference, functions

Lowercase primitives with hover-to-see inference; un-annotated values silently become any. Annotate at boundaries — const getHello = (s: string): string — and let inference carry locals (heroes.map needs no annotations).


099-03 aliases, tuples, enums

The signup/Card reshuffle motivates type aliases; RGB triples motivate tuples (mistyped position errors TS2322); SeatChoice goes numeric → string → mixed in one file so the enum tradeoff is visible.


099-04 interfaces and classes

Object interfaces, then the User model: constructor assignment, readonly city rejected on reassignment, private/protected/public, getters/setters — then interfaces-vs-types and abstract bases whose children carry the responsibility.


099-05 generics and narrowing

<T> placeholders preserving the caller’s exact type up to getPropertyValue<T, K extends keyof T>; then detection.ts — in-operator narrowing on User | Admin and the exhaustive never switch, so unhandled shapes become compile errors.


099 coverage map (modules 00–05)

modulecourse coveragenarrative section
00 start (env, js-to-ts)Node check, first tsc compile, tsconfig strict family099-01
01 why (safety net, tsc)better-JavaScript discipline framing099-01
02 basics (inference, any/unknown/never)lowercase primitives, inference vs any, typed functions099-02
03 shapes (arrays, tuples, interfaces, optional/readonly)aliases, arrays, unions, RGB tuples, SeatChoice enums, interfaces, readonly099-03, 099-04
04 functions (signatures, unions, narrowing, guards)detection.ts: typeof/in/instanceof, predicates, exhaustive never099-05
05 architecture (literals, enums, generics, utility)classes, abstract classes, generics, discriminated unions099-04, 099-05
06 config (tsconfig strict, MCP)strict flags as a dial (setup revisit only)—
07 capstone (analyst agent)not covered—

Gaps (source from other itinerary videos): utility types (Partial/Omit — see 023), unknown/never as standalone topics, DOM integration.


099 screenshot refs

  • frame-0001.png (00:24:32) — first tsc intro.ts compile in the terminal
  • frame-0002.png (01:09:36) — typed getHello and heroes.map
  • frame-0003.png (01:29:38) — User alias applied to createUser
  • frame-0004.png (02:09:41) — tuple type error (TS2322) on a mistyped triple
  • frame-0005.png (02:17:42) — SeatChoice enum, numeric then string members
  • frame-0006.png (03:01:45) — readonly city rejected on reassignment
  • frame-0007.png (03:51:49) — generic search over a Bootle interface
  • frame-0008.png (04:21:52) — in-operator narrowing on User | Admin

Full narrative: 099 — Learn TypeScript – Full Tutorial (Hitesh, setup to detection.ts) — the complete lesson with all 8 screenshots, code blocks, coverage map, and transcript corrections.

↑ contents


full course 100 — The TypeScript Course for JS Devs (K01hLNDdqg4, ~4:24:18)

Boot.dev’s lesson-by-lesson course walkthrough for JavaScript developers: assignment prompts, editor code, run/test panels, every feature tied back to runtime behavior. The through-line is composability — primitives, literals, unions, objects, and generics compose into whatever shape the runtime already has. Arc: compile-time-only types, function defaults/optionals, EmploymentStatus literal unions, as const, the Character interface-vs-type hierarchy, Direction enums and the const enum tradeoff, unknown/any/never, in narrowing, implements contracts, Partial refactors, constrained generics (pair<A, B> zipper), conditional types with string-pattern matching, keyof soldier lookups, modules, and strictness toggles — closing on Vite config.

Transcription note: Whisper mistranscriptions corrected — “Vite” (not “Veet”), Boot.dev, files.get(...).

chapters


100-01 composability, defaults, literals

A third category of types exists only at compile time. Defaults make parameters optional (greet("Gandalf") vs greet("Gandalf", "Wizard")); literals denote specific values and unions compose them (EmploymentStatus = "employed" | "unemployed" | "student").


100-02 objects, interfaces, enums

as const readonly literals vs runtime Object.freeze; the Character hierarchy (incompatible extensions break); Direction enums with the const enum tradeoff (no runtime overhead, but no reverse mapping).


100-03 widest types, narrowing, utility

unknown as the safe wide type, null-handling, in-operator and discriminated narrowing with failure handling, implements contracts, and Partial<T> update-payload refactors.


100-04 generics, conditional types, keyof

T extends { cost: number } constraints, the pair<A, B> zipper returning [A, B][], conditional types reading like ternaries (SomeType extends OtherType ? TrueType : FalseType), and keyof mapped types rebuilding Soldier fully optional.


100 coverage map (modules 00–05)

modulecourse coveragenarrative section
00 start (env, js-to-ts)JS-dev premise, parsing/validation exercises100-01
01 why (safety net, tsc)runtime-behavior tie-in for every feature100-01
02 basics (inference, any/unknown/never)defaults/optionals, literals, unions, unknown/any/never, as const100-01, 100-03
03 shapes (arrays, tuples, interfaces, optional/readonly)objects, rest params, interfaces vs type, enums/const enum, null-handling100-02
04 functions (signatures, unions, narrowing, guards)in narrowing, discriminated checks, implements100-03
05 architecture (literals, enums, generics, utility)utility types, generics + constraints, conditional types, keyof100-03, 100-04
06 config (tsconfig strict, MCP)strictness toggles, modules/exports, Vite config—
07 capstone (analyst agent)not covered—

Gaps (source from other itinerary videos): DOM integration, framework usage, decorators, declaration files.


100 screenshot refs

  • frame-0001.png (00:36:33) — greet with default and optional parameters
  • frame-0002.png (00:49:33) — EmploymentStatus union exercise
  • frame-0003.png (02:12:39) — Character interface with incompatible extension
  • frame-0004.png (02:24:40) — const enum limitation quiz
  • frame-0005.png (03:14:44) — Partial utility type on User
  • frame-0006.png (03:27:44) — generic pair preserving both element types
  • frame-0007.png (03:39:45) — conditional types definition
  • frame-0008.png (03:52:46) — keyof mapped type over Soldier

Full narrative: 100 — The TypeScript Course for JS Devs (Boot.dev, composability to conditional types) — the complete lesson with all 8 screenshots, chapter list, coverage map, and transcript corrections.

↑ contents


full course 160 — TypeScript Full Course 2026 | Learn TypeScript in One Video (W3G4DuchKFY)

Sangam Mukherjee single-video full course. This video provides a comprehensive overview of TypeScript, covering foundational concepts, advanced type systems, and practical applications. It begins with an introduction to TypeScript’s core features such as type annotations, type inference, and primitive types. The course then progresses to more complex topics like unions, intersections, tuples, and generics. It also covers object-oriented pr

Full narrative: 160 — TypeScript Full Course 2026 | Learn TypeScript in One Video (single-video full course)

TypeScript Q&A Coach

PLACEHOLDER: The coach widget will be included here once extracted from the typescript-understanding SPA.

full narratives

Each video below has a full companion narrative with screenshots: