jestjs/jest · error · TypeError

@jest/diff-sequences: ${name} typeof ${type} is not a functi

Error message

@jest/diff-sequences: ${name} typeof ${type} is not a function

What it means

diffSequence validates isCommon and foundSubsequence with validateCallback, requiring typeof === 'function'. The algorithm calls back into these functions to report matches; a non-function would throw a less helpful error mid-algorithm, so diff-sequences fails fast up front.

Source

Thrown at packages/diff-sequences/src/index.ts:774

  }
};

const validateLength = (name: string, arg: unknown) => {
  if (typeof arg !== 'number') {
    throw new TypeError(`${pkg}: ${name} typeof ${typeof arg} is not a number`);
  }
  if (!Number.isSafeInteger(arg)) {
    throw new RangeError(`${pkg}: ${name} value ${arg} is not a safe integer`);
  }
  if (arg < 0) {
    throw new RangeError(`${pkg}: ${name} value ${arg} is a negative integer`);
  }
};

const validateCallback = (name: string, arg: unknown) => {
  const type = typeof arg;
  if (type !== 'function') {
    throw new TypeError(`${pkg}: ${name} typeof ${type} is not a function`);
  }
};

// Compare items in two sequences to find a longest common subsequence.
// Given lengths of sequences and input function to compare items at indexes,
// return by output function the number of adjacent items and starting indexes
// of each common subsequence.
export default function diffSequence(
  aLength: number,
  bLength: number,
  isCommon: IsCommon,
  foundSubsequence: FoundSubsequence,
): void {
  validateLength('aLength', aLength);
  validateLength('bLength', bLength);
  validateCallback('isCommon', isCommon);
  validateCallback('foundSubsequence', foundSubsequence);

View on GitHub (pinned to f49721c78e)

Solutions

  1. Pass actual functions for both callbacks: an (aIndex, bIndex) => boolean isCommon and an (nCommon, aCommon, bCommon) => void foundSubsequence.
  2. If forwarding callbacks, ensure they are defined and are functions before calling diffSequence.
  3. Bind methods: `obj.callback.bind(obj)` rather than passing `obj.callback` unbound when `this` matters.

Example fix

// before — 4th argument missing/undefined
diffSequence(a.length, b.length, (i, j) => a[i] === b[j]);

// after
diffSequence(
  a.length,
  b.length,
  (i, j) => a[i] === b[j],
  (nCommon, aCommon, bCommon) => { console.log('match', {nCommon, aCommon, bCommon}); },
);
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof isCommon !== 'function' || typeof foundSubsequence !== 'function') {
  throw new TypeError('diffSequence callbacks must be functions');
}

Type guard

function isCallback(x: unknown): x is (...args: number[]) => unknown {
  return typeof x === 'function';
}

Try / catch

try {
  diffSequence(aLength, bLength, isCommon, foundSubsequence);
} catch (e) {
  if (e instanceof TypeError && /is not a function/.test(e.message)) { /* default no-op or rebind */ }
  throw e;
}

Prevention

When it happens

Trigger: Calling diffSequence with isCommon or foundSubsequence that is not a function: passing undefined (omitted arg), an arrow stored in a variable that was never assigned, an object/method reference that wasn't bound, or a string name of a method by mistake.

Common situations: Refactoring that drops the 4th argument; passing a method reference without binding; copy-paste leaving a placeholder null for a callback.

Related errors


AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03). Data as JSON: /data/errors/38e5fd3fe2245c8d.json. Report an issue: GitHub.