trekhleb/javascript-algorithms · error · TypeError

Cannot construct Heap instance directly

Error message

Cannot construct Heap instance directly

What it means

Heap is an abstract base class for MinHeap and MaxHeap; its ordering hook pairIsInCorrectOrder() is deliberately unimplemented (it always throws, Heap.js:280-285), so a bare Heap could never order elements. The constructor guard `new.target === Heap` (Heap.js:12-14) makes that contract explicit by throwing a TypeError the instant new Heap(...) runs - the same pattern as abstract-class enforcement in other languages.

Source

Thrown at src/data-structures/heap/Heap.js:13

import Comparator from '../../utils/comparator/Comparator';

/**
 * Parent class for Min and Max Heaps.
 */
export default class Heap {
  /**
   * @constructs Heap
   * @param {Function} [comparatorFunction]
   */
  constructor(comparatorFunction) {
    if (new.target === Heap) {
      throw new TypeError('Cannot construct Heap instance directly');
    }

    // Array representation of the heap.
    this.heapContainer = [];
    this.compare = new Comparator(comparatorFunction);
  }

  /**
   * @param {number} parentIndex
   * @return {number}
   */
  getLeftChildIndex(parentIndex) {
    return (2 * parentIndex) + 1;
  }

  /**
   * @param {number} parentIndex
   * @return {number}

View on GitHub (pinned to 85293e3e2b)

Solutions

  1. Instantiate a concrete subclass: new MinHeap(comparatorFunction) or new MaxHeap(comparatorFunction) - both accept an optional comparator, so custom ordering usually needs no subclass.
  2. For truly custom ordering, extend Heap and implement pairIsInCorrectOrder(first, second) (return first <= second for a min-heap), then instantiate your subclass.
  3. In a factory, default the class parameter to a concrete one: function makeHeap(Ctor = MinHeap) { return new Ctor(); }
  4. Check imports: Heap should never appear after `new` outside its own subclasses.

Example fix

// before
import Heap from './heap/Heap';
const heap = new Heap((a, b) => a - b); // TypeError: Cannot construct Heap instance directly

// after
import MinHeap from './heap/MinHeap';
const heap = new MinHeap((a, b) => a - b);
Defensive patterns

Strategy: type-guard

Type guard

import Heap from '../heap/Heap';
import MinHeap from '../heap/MinHeap';
import MaxHeap from '../heap/MaxHeap';

// True only for constructors that may legally follow `new`
const isConcreteHeapClass = (Ctor) =>
  Ctor === MinHeap || Ctor === MaxHeap || Ctor.prototype instanceof Heap;

function makeHeap(Ctor = MinHeap, comparator) {
  if (!isConcreteHeapClass(Ctor)) {
    throw new TypeError('Heap subclasses only; Heap itself is abstract');
  }
  return new Ctor(comparator);
}

Try / catch

try {
  heap = new HeapClass(comparator);
} catch (error) {
  if (error instanceof TypeError && /Cannot construct Heap instance directly/.test(error.message)) {
    heap = new MinHeap(comparator); // fall back to a concrete heap
  } else {
    throw error;
  }
}

Prevention

When it happens

Trigger: new Heap() or new Heap((a, b) => a - b); a generic factory that receives the class by variable (new Ctor(cmp) where Ctor === Heap); importing Heap because it is the first hit when searching the package for 'heap'.

Common situations: Wanting 'just a heap' and instantiating the base class picked by an IDE auto-import; porting code from a library where Heap itself is concrete; factory code that defaults its class parameter to the base instead of a subclass.

Related errors


AI-assisted analysis of trekhleb/javascript-algorithms@85293e3e2b (2026-08-24). Data as JSON: /api/errors/cdfb28ee57bb3e2d. Report an issue: GitHub.