All tracks

JavaScript / TypeScript

Re-sharpen the JS/TS details that atrophy first: coercion, closures, this, the event loop, and a type system you drive instead of fight.

71 concepts426 live tasks
Start practicing free

What's inside

Language Core & Coercion

var hoists to undefined; let and const hoist into the TDZ
== follows an algorithm, not vibes
ToPrimitive: valueOf, toString, and Symbol.toPrimitive
+ is the only operator that concatenates
Three equality algorithms: ===, SameValueZero, Object.is
?? only skips null/undefined; || skips every falsy
Every number is a float64, until it can't be

Functions, Scope & Closures

Function declarations hoist whole; expressions don't
Closures capture variables, not values
let creates a fresh binding per loop iteration; var doesn't
Arrows have no this, arguments, new.target, or prototype
Default parameters evaluate lazily, in their own scope
Partial application is just a closure factory
Closures can retain more memory than they use

this, Prototypes & Classes

this is decided at the call site, by four rules
Extracting a method detaches its this
Arrow this is resolved like a variable lookup
Property reads walk the chain; writes don't
What new actually does (and when return hijacks it)
Class fields live per-instance; methods live on the prototype
#private is real privacy, not a convention
Property descriptors: the machinery under every object

The Event Loop & Async

One thread, a task queue, and a run-to-completion contract
The microtask queue drains completely between tasks
Every .then returns a new promise; the callback's return decides its fate
await suspends the function, not the thread
try/catch works across await, with sharp edges
A promise nobody awaits fails silently, until it doesn't
all, allSettled, race, any: four failure semantics
Awaiting in a loop serializes; start first, await after

Iterators, Generators & Collections

Symbol.iterator is the contract behind for-of and spread
Generators are pausable functions that produce iterators
next(v), throw(e), return(v): callers talk back to generators
for await consumes streams one settled value at a time
Map is for dynamic keys; objects are for records
WeakMap keys don't keep their objects alive
WeakRef and FinalizationRegistry: GC as an observable, barely
Spread copies one level; structuredClone goes deep

Modules & Tooling Realities

ESM exports are live bindings; CJS exports are a snapshot object
The interop layer: default imports, __esModule, and the dual-package hazard
Circular imports don't error; they hand you incomplete modules
import() is the code-splitting seam
Tree-shaking is dead-code elimination gated on purity
package.json exports: the map that decides what importers see
Top-level await makes module loading asynchronous for everyone upstream
Declaration merging: how libraries let you extend their types

TypeScript Type System Fundamentals

TypeScript compares shapes, not names
Literals widen unless something anchors them
interface vs type: fewer differences than the arguments about them
Narrowing is control-flow analysis over your ifs
unknown is the honest any
Discriminated unions make illegal states unrepresentable
Fresh object literals get stricter checking, deliberately
satisfies: validate against a type without widening to it
Partial, Pick, Omit, ReturnType: derive types, don't duplicate them

Advanced Types & Generics

Generics preserve the relationship between input and output
Where the compiler infers T from, and why it sometimes picks wrong
keyof and T[K]: types that index like values do
Conditional types are if-statements evaluated by the compiler
infer: destructuring for types
Conditionals distribute over naked union parameters
Mapped types: iterate over keys, transform, even rename
Template literal types: string manipulation in the type system
Variance: why Array<Dog> isn't safely an Array<Animal>

Runtime Edge Cases & Performance

Hidden classes: why property order and shape stability matter
Packed vs holey, SMI vs double: arrays have internal kinds
GC collects the unreachable: leaks are unintended reachability
JSON.stringify drops, mangles, and throws by spec
Proxy traps object operations; Reflect forwards them correctly
Microtasks can starve rendering and I/O
Catastrophic backtracking: the regex that takes down the service