Task Queues in TypeScript: A Complete Guide for Beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction to Task Queues in TypeScript



A task queue (Queue) is one of the fundamental data structures in programming, operating on the FIFO principle (First In, First Out). Imagine a regular queue at a store: the first customer who gets in line is served first. In programming, task queues are used everywhere: from processing requests on a server to managing asynchronous operations in the browser.



In this article, we will explore how to create and use a task queue in TypeScript. You will learn how to type a queue, implement basic methods, and apply it in real projects. The material is designed for beginner developers familiar with the basics of TypeScript.



Basic Queue Operations



Any task queue must support several basic operations:



  • enqueue (add an element to the end of the queue);
  • dequeue (remove an element from the front of the queue);
  • peek (view the first element without removing it);
  • isEmpty (check if the queue is empty);
  • size (get the number of elements).


In TypeScript, we can implement a queue based on an array or a linked list. For simplicity, we'll start with an array.



Array-Based Queue Implementation



Let's create a Queue<T> class using generics — this will allow storing data of any type:



class Queue<T> {    private items: T[] = [];

// Add an element to the end of the queue enqueue(element: T): void { this.items.push(element); }

// Remove and return the first element dequeue(): T | undefined { return this.items.shift(); }

// View the first element without removing it peek(): T | undefined { return this.items[0]; }

// Check if the queue is empty isEmpty(): boolean { return this.items.length === 0; }

// Get the queue size size(): number { return this.items.length; }}


Now you can create a queue for any data type:



// String queueconst stringQueue = new Queue<string>();stringQueue.enqueue('Task 1');stringQueue.enqueue('Task 2');console.log(stringQueue.dequeue()); // 'Task 1'

// Number queueconst numberQueue = new Queue<number>();numberQueue.enqueue(10);numberQueue.enqueue(20);console.log(numberQueue.peek()); // 10


Drawbacks of Array-Based Implementation



The shift() method in JavaScript/TypeScript has a complexity of O(n), because after removing the first element, all others are shifted. For large amounts of data, this is inefficient. The solution is to implement a queue based on an object or a linked list.



Optimized Queue with an Object



To avoid shifting elements, we will store elements in an object and track the start and end indices:



class OptimizedQueue<T> {    private items: Record<number, T> = {};    private head: number = 0;    private tail: number = 0;

enqueue(element: T): void { this.items[this.tail] = element; this.tail++; }

dequeue(): T | undefined { if (this.isEmpty()) { return undefined; } const item = this.items[this.head]; delete this.items[this.head]; this.head++; return item; }

peek(): T | undefined { return this.items[this.head]; }

isEmpty(): boolean { return this.tail === this.head; }

size(): number { return this.tail - this.head; }}


Now the enqueue and dequeue operations are performed in O(1) — constant time, regardless

Blogs

Book Recommendations