data-structure-typed: A Modern Data Structures Library for TypeScript
Source: Dev.to
Why I Built data-structure-typed: A Modern Data‑Structures Library for TypeScript
TL;DR: After years of using various data‑structure libraries in JavaScript/TypeScript, I built one that prioritises type safety, native‑API familiarity, and performance. Here’s what I learned.
The Problem
If you’ve worked on algorithm‑heavy TypeScript projects, you’ve probably faced this dilemma:
| Issue | Details |
|---|---|
| Native JS | Only provides Array, Map, Set, and plain objects – no trees, heaps, or graphs. |
| Existing libraries | Often have inconsistent APIs, poor TypeScript support, or expose too many internals. |
I wanted something that felt like a natural extension of JavaScript’s built‑in collections – with the same API patterns, full type safety, and solid performance.
What is data-structure-typed?
A comprehensive collection of data structures for JavaScript and TypeScript:
- Binary Trees – BST, AVL Tree, Red‑Black Tree,
TreeMap,TreeSet - Heaps – Min/Max Heap, Priority Queue
- Graphs – Directed, Undirected (with Dijkstra, Bellman‑Ford, Floyd‑Warshall, etc.)
- Linear – Queue, Deque, Stack, Singly/Doubly Linked List
- Others – Trie, HashMap, and more
Design Philosophy
1. Native API Familiarity
If you know JavaScript’s Map and Set, you already know how to use TreeMap and TreeSet:
import { TreeMap, TreeSet } from 'data-structure-typed';
// Works just like native Map, but keys are always sorted
const map = new TreeMap();
map.set('banana', 3);
map.set('apple', 1);
map.set('cherry', 2);
console.log([...map.keys()]); // ['apple', 'banana', 'cherry'] – sorted!
// Works just like native Set, but elements are always sorted
const set = new TreeSet([3, 1, 4, 1, 5, 9, 2, 6]);
console.log([...set]); // [1, 2, 3, 4, 5, 6, 9] – sorted & deduplicated!
2. Full TypeScript Support
Everything is fully typed with generics. No any types leak through:
interface User {
id: number;
name: string;
score: number;
}
// Type‑safe priority queue
const leaderboard = new MaxPriorityQueue({
comparator: (a, b) => a.score - b.score,
});
leaderboard.add({ id: 1, name: 'Alice', score: 100 });
leaderboard.add({ id: 2, name: 'Bob', score: 150 });
const top = leaderboard.poll(); // User | undefined
console.log(top?.name); // 'Bob'
3. Navigation Methods (Java‑style)
TreeMap and TreeSet include Java’s NavigableMap/NavigableSet methods:
const prices = new TreeMap([
[10, 'cheap'],
[50, 'medium'],
[100, 'expensive'],
[500, 'luxury'],
]);
prices.floor(75); // [50, 'medium'] – largest key ≤ 75
prices.ceiling(75); // [100, 'expensive'] – smallest key ≥ 75
prices.lower(50); // [10, 'cheap'] – largest key 50
4. Functional Methods
All collections support map, filter, reduce, forEach:
const numbers = new TreeSet([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
const evens = numbers.filter((n) => n % 2 === 0);
console.log([...evens]); // [2, 4, 6, 8, 10]
const doubled = numbers.map((n) => n * 2);
console.log([...doubled]); // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Performance
Under the hood, TreeMap and TreeSet use Red‑Black Trees. Below is a quick comparison with the popular js-sdsl library (benchmarks run on Node.js 22, Apple M1):
| Operation (100 K) | data-structure-typed | js-sdsl |
|---|---|---|
| set | 1.00× (baseline) | 1.54× slower |
| get | 1.00× | 1.02× |
| delete | 1.22× | 1.00× |
| iterate | 1.00× | 2.15× slower |
The biggest win is iteration – we’re ~2× faster thanks to an optimized iterator implementation.
Real‑World Use Cases
LeetCode / Competitive Programming
// LeetCode 729: My Calendar I
class MyCalendar {
private bookings = new TreeMap();
book(start: number, end: number): boolean {
const prev = this.bookings.floor(start);
const next = this.bookings.ceiling(start);
if (prev && prev[1] > start) return false;
if (next && next[0] ({
comparator: (a, b) => a.priority - b.priority,
});
// Add tasks
taskQueue.add({ id: 1, priority: 3, name: 'Low priority' });
taskQueue.add({ id: 2, priority: 1, name: 'Urgent!' });
taskQueue.add({ id: 3, priority: 2, name: 'Medium' });
// Process in priority order
while (!taskQueue.isEmpty()) {
const task = taskQueue.poll()!;
console.log(`Processing: ${task.name}`);
}
// Output: Urgent! → Medium → Low priority
Graph Algorithms
const graph = new DirectedGraph();
graph.addVertex('A');
graph.addVertex('B');
graph.addVertex('C');
graph.addEdge('A', 'B', 1);
graph.addEdge('B', 'C', 2);
graph.addEdge('A', 'C', 5);
const { distMap } = graph.dijkstra('A');
console.log(distMap.get('C')); // 3 (A→B→C is shorter than A→C)
Installation
npm install data-structure-typed
Or install individual packages for smaller bundles:
npm install tree-map-typed # Just TreeMap
npm install heap-typed # Just Heap / PriorityQueue
What’s Next?
- Ongoing performance improvements (we’re always benchmarking)
- More LeetCode‑style examples in the documentation
- Interactive playground
Links
GitHub: (repo)
npm: (package)
npm: https://www.npmjs.com/package/data-structure-typed
Docs: https://data-structure-typed-docs.vercel.app
If you’re working on anything that needs proper data structures in TypeScript, give it a try. PRs and issues welcome!
What data structures do you wish JavaScript had natively? Let me know in the comments!