microsoft/TypeScript · error · TypeError
Class extends value ${String(b)} is not a constructor or nul
Error message
Class extends value ${String(b)} is not a constructor or null What it means
`__extends` downlevels class heritage for ES5 targets. It throws if the base value `b` is neither a function nor null, because only a constructor (or null) is a legal class-extends target.
Source
Thrown at src/compiler/factory/emitHelpers.ts:950
// ES2015 Helpers
const extendsHelper: UnscopedEmitHelper = {
name: "typescript:extends",
importName: "__extends",
scoped: false,
priority: 0,
text: `
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();`,
};
const templateObjectHelper: UnscopedEmitHelper = {
name: "typescript:makeTemplateObject",
importName: "__makeTemplateObject",
scoped: false,
priority: 0,
text: `
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
};`,
};
View on GitHub (pinned to b465fdbfe1)
Solutions
- Ensure the extended expression evaluates to a constructor (class/function) or null.
- Resolve circular imports so the base is fully initialized before the subclass definition runs.
- If extending null intentionally, write `extends null` explicitly.
Example fix
// before
// a.js: export const Base = 5; // not a constructor
// b.js: import { Base } from "./a"; class Sub extends Base {} // throws
// after
// a.js: export class Base {}
// b.js: import { Base } from "./a"; class Sub extends Base {} Defensive patterns
Strategy: type-guard
Validate before calling
function assertExtensible(base: unknown): void {
if (typeof base !== "function" && base !== null) {
throw new TypeError(`Class extends value ${String(base)} is not a constructor or null`);
}
} Type guard
function isConstructorOrNull(v: unknown): v is (new (...args: any[]) => any) | null {
return v === null || typeof v === "function";
} Prevention
- Break circular imports so the base is initialized before the subclass is evaluated.
- Validate mixins return a function before extending them.
- Use `extends null` explicitly when extending null.
When it happens
Trigger: `class X extends Y` where Y evaluates at runtime to a non-function, non-null value: a number, string, plain object, or `undefined`.
Common situations: Circular import causing the base to be undefined at class-evaluation time; a mixin computed to a non-function; extending a const before its declaration (TDZ-like effect in transpiled output).
Related errors
- Function expected
- Cannot add initializers after decoration has completed
- Object expected
- Symbol.asyncIterator is not defined.
- Object is not iterable.
AI-assisted analysis of microsoft/TypeScript@b465fdbfe1 (2026-08-12).
Data as JSON: /api/errors/e8869c915c50b073.
Report an issue: GitHub.