TypeScript implementations and exercises based on Grokking Algorithms by Aditya Bhargava, written and tested with TypeScript 7.
Each algorithm lives in its own folder under algorithms/, prefixed with the number of the
book chapter it comes from so it's obvious at a glance where each one fits:
algorithms/
01-binary-search/
binary-search.ts
binary-search.test.ts
NN-<algorithm-name>/
<algorithm-name>.ts
<algorithm-name>.test.ts
To add a new algorithm, create a new NN-<algorithm-name>/ folder under algorithms/ (see the
chapter reference table below for NN) with an implementation file and a matching *.test.ts
file with Vitest unit tests.
Some chapters also have small book exercises tied to a subtopic rather than a named algorithm
(e.g. chapter 4 introduces divide and conquer before quicksort, with exercises like "write a
recursive function that sums a list") — those live grouped under a NN-<subtopic>/<name>/
folder for that chapter instead of getting their own top-level entries:
algorithms/
04-divide-and-conquer/
sum/
sum.ts
sum.test.ts
count/
max/
Beyond unit tests, two extra tools are wired up specifically to build intuition about why an algorithm's complexity matters, which is the whole point of the book:
-
Benchmarking (
npm run bench) — uses Vitest's built-in bench mode (backed by tinybench, already a Vitest dependency, so nothing extra to install). Seealgorithms/01-binary-search/binary-search.bench.tsfor an example that times binary search (O(log n)) against a linear scan (O(n)) on the same data — a good way to make Big O differences concrete instead of abstract. Add a*.bench.tsfile next to any algorithm to compare it against a naive approach or another implementation. -
Property-based testing (fast-check) — rather than only checking a handful of hand-picked examples,
fc.assert(fc.property(...))generates hundreds of random inputs and checks an invariant holds for all of them (e.g. "for any sorted array, binary search finds the same index asindexOf"). This tends to catch off-by-one and edge case bugs — exactly the kind that are easy to miss when translating an algorithm from the book into code. Seealgorithms/01-binary-search/binary-search.property.test.tsfor an example; name these files*.property.test.tsso they're picked up bynpm testalongside regular unit tests.
| Command | What it does |
|---|---|
npm run typecheck |
Type-check the project without emitting output |
npm test |
Run the Vitest test suite once |
npm run test:watch |
Run Vitest in watch mode |
npm run bench |
Run benchmarks once (Vitest's built-in bench mode) |
npm run bench:watch |
Run benchmarks in watch mode |
npm run build |
Compile TypeScript to dist/ |
npm run lint |
Lint with ESLint |
npm run lint:fix |
Lint and auto-fix |
npm run format |
Format all files with Prettier |
npm run format:check |
Check formatting without writing changes |
TypeScript 7 is the new native (Go-based) compiler and ships without a programmatic JS API.
Tools that need that API for type-aware features — here, @typescript-eslint/* — aren't
compatible with it yet, so this repo follows Microsoft's documented workaround
(TS 7 announcement):
typescriptis aliased to@typescript/typescript6, the TS 6 API compatibility shim, so tooling like ESLint keeps working.@typescript/nativeis aliased to the realtypescript@7, providing the nativetscbinary used bynpm run build/npm run typecheck.
Both are declared in package.json; you don't need to do anything special day-to-day —
tsc is TypeScript 7.
npm install
npm testA rough map from the book's chapters to algorithm/topic names, useful when deciding what
folder to create next. The NN- prefix always matches the chapter number:
| Chapter | Topic | Folder name |
|---|---|---|
| 1 | Binary search | 01-binary-search (done) |
| 2 | Selection sort | 02-selection-sort (done) |
| 3 | Recursion (factorial) | 03-factorial (done) |
| 4 | Divide & conquer, quicksort | 04-divide-and-conquer (exercises done), 04-quicksort (done) |
| 5 | Hash tables | 05-hash-table (done) |
| 6 | Breadth-first search | 06-breadth-first-search |
| 7 | Trees / Dijkstra's algorithm | 07-dijkstra |
| 8 | Greedy algorithms | 08-greedy-set-cover |
| 9 | Dynamic programming | 09-dynamic-programming |
| 10 | K-nearest neighbors | 10-k-nearest-neighbors |
This is only a starting point — feel free to name folders however makes sense as you work
through the book, as long as the NN- chapter prefix stays consistent.