'TypeError: Class extends value undefined is not a function or null

I am getting the following error when trying to create these entities.

TypeError: Class extends value undefined is not a function or null

I am assuming this has something to do with circular dependencies, but how is that supposed to be avoided when using table inheritance and one to many relationships?

It is complaining about the following javascript at BaseComic_1.BaseComic.

let Variant = class Variant extends BaseComic_1.BaseComic {

Here is the complete file.

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
const typeorm_1 = require("typeorm");
const Comic_1 = require("./Comic");
const BaseComic_1 = require("./BaseComic");
let Variant = class Variant extends BaseComic_1.BaseComic {
};
__decorate([
    typeorm_1.ManyToOne(type => Comic_1.Comic, comic => comic.variants),
    __metadata("design:type", Comic_1.Comic)
], Variant.prototype, "comic", void 0);
Variant = __decorate([
    typeorm_1.ClassEntityChild()
], Variant);
exports.Variant = Variant;
//# sourceMappingURL=Variant.js.map

import {Entity, Column, PrimaryGeneratedColumn, OneToMany} from "typeorm";
import {Comic} from "./Comic";

@Entity()
export class Series {

    @PrimaryGeneratedColumn()
    public id: number;

    @Column("text", {
        length: 30
    })
    public copyright: string;

    @Column("text", {
        length: 100
    })
    public attributionText: string;

    @Column("text", {
        length: 150
    })
    public attributionHTML: string;

    @Column("text", {
        length: 50
    })
    public etag: string;

    @Column("text", {
        length: 200
    })
    public title: string;

    @Column("text")
    public description: string;

    @Column("number", {
        length: 4
    })
    public startYear: number;

    @Column("number", {
        length: 4
    })
    public endYear: number;

    @Column("text", {
        length: 20
    })
    public rating: string;

    @Column("text", {
        length: 20
    })
    public type: string;

    @Column("text")
    public thumbnail: string;

    @OneToMany(type => Comic, comic => comic.series)
    public comics: Array<Comic>;
}

import {Entity, TableInheritance, PrimaryGeneratedColumn, Column, ManyToOne, DiscriminatorColumn} from "typeorm";
import {Series} from "./Series";

@Entity()
@TableInheritance("class-table")
@DiscriminatorColumn({ name: "type", type: "string"})
export class BaseComic {

    @PrimaryGeneratedColumn()
    public id: number;

    @Column("text", {
        length: 30
    })
    public copyright: string;

    @Column("text", {
        length: 100
    })
    public attributionText: string;

    @Column("text", {
        length: 150
    })
    public attributionHTML: string;

    @Column("text", {
        length: 50
    })
    public etag: string;

    @Column("text", {
        length: 200
    })
    public title: string;

    @Column("int")
    public issue: number;

    @Column("text")
    public variantDescription: string;

    @Column("boolean")
    public variant: boolean;

    @Column("text")
    public description: string;

    @Column("int")
    public pageCount: number;

    @Column("date")
    public onSaleDate: Date;

    @Column("date")
    public unlimitedDate: Date;

    @Column("text")
    public thumbnail: string;

    @ManyToOne(type => Series, series => series.comics)
    public series: Series;
}

import {OneToMany, ClassEntityChild} from "typeorm";
import {Variant} from "./Variant";
import {BaseComic} from "./BaseComic";

@ClassEntityChild()
export class Comic extends BaseComic {

    @OneToMany(type => Variant, variant => variant.comic)
    public variants: Variant[];
}

import {ManyToOne, ClassEntityChild} from "typeorm";
import {Comic} from "./Comic";
import {BaseComic} from "./BaseComic";

@ClassEntityChild()
export class Variant extends BaseComic {

    @ManyToOne(type => Comic, comic => comic.variants)
    public comic: Comic;
}


Solution 1:[1]

I was having the same issue. It turns out I was circularly importing classes, which is apparently a limitation. (See these GitHub issues: #20361, #4149, #10712)

Note that it seems that the circular reference is also limited between files, not simply types.

See this other answer

Solution 2:[2]

As noted in Thomas Jensen's comment above, circular references can occur not just in Types, but also in files. I encountered this same problem when I was exporting both the base and derived types from the same file. Such as:

// index.ts
export { BaseClass } from "./base";
export { DerivedClass } from "./derived";

This is an easy pitfall to fall into. Posting this here in the hopes it'll save someone else the debugging time.

Solution 3:[3]

Circular dependencies can be tricky to identify. Michael Weststrate has an interesting reading about circular dependencies and proposed a pattern to fix them.

Automated circular dependency detection.

On top of using a pattern that allows for scalability, you can make use of a super useful tool that with very little effort will identify circular dependencies for you, Madge.

Madge can be ran over .ts or .js files. I found that is useful to run it in both directories, as they might give different results due to the transpilation process.

For Typescript .ts files:

madge --circular --extensions ts <directory_path>

For Javascript .js files:

madge --circular <directory_path>

Solution 4:[4]

I came here because when executing the code with jest, it threw this error. This is because when writing the moduleNameMapper for the jest.config.js the order of the elements in the object is essential.

There is a helper which imports the module-names from the ts-config.json:

// jest.config.js
const { pathsToModuleNameMapper } = require('ts-jest/utils');
// In the following statement, replace `./tsconfig` with the path to your `tsconfig` file
// which contains the path mapping (ie the `compilerOptions.paths` option):
const { compilerOptions } = require('./tsconfig');

module.exports = {
  // [...]
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths /*, { prefix: '<rootDir>/' } */ )
};

Taken from the official documentation of ts-jest

Solution 5:[5]

Just ran into this issue and, well, it is strange. I am running the project as

node --require ts-node/register path/to/index.ts

And this failed with above error even after I removed circular references as suggested by accepted answer.

However, if I run tsc it compiles fine and then it runs fine even with --require ts-node/register....

Hope this helps someone.

Solution 6:[6]

For me, it was not circular dependency. This is for Angular web app.

I had an abstract class:

export abstract class BaseService {
  ...
}

and I was trying to extend it to implement an Angular service,

@Injectable({
  providedIn: 'root'
})
export class MyExtendedService extends BaseService {

But, I keep getting the error TypeError: Class extends value undefined is not a function or null in my app.module.ts where I was implementing this extension.

After lot of trial and error, I found out that I had to add @Injectable to the base class also. So, I updated my base class to:

@Injectable()
export abstract class BaseService {
  ...
}

and then, everything worked fine.

Solution 7:[7]

I had the same problem because my editor auto-imported Entity from the wrong package.

Once I changed import { Entity } from 'typeorm/decorator/entity/Entity'; back to import { Entity } from 'typeorm'; the error message disappeared.

Solution 8:[8]

In my node typescript project, I was using import/export syntax (over require).

I had this error in a file where I forgot to get rid of the module.exports syntax :

module.exports = { AbstractClass } // this will cause issues if you use import/export syntax

I just had to remove it and simply use the "export" key word

export class AbstractClass { /* stuff */ }

Solution 9:[9]

1. Designing a React Component:

class Card extends React.Compoonent {

See the typo: Compoonent

2. Installing Angular on Windows fails with error:

TypeError: Class extends value undefined is not a function or null

  1. Start > Run > AppWiz.cpl > Uninstall node.js

  2. Delete the node install directory removing remaining folders and files

  3. Delete npm folder from Start > Run > %AppData% (AppData\Roaming)

  4. If it exists delete npm-cache from the c:\users[username} directory

  5. Install node.js the Latest Version and please use the default C:\Program Files\nodejs install path.

  6. Open Cmd:


C:\Users\Jeremy>node -v
v17.1.0

C:\Users\Jeremy>npm -v
8.1.2

Solution 10:[10]

I received this error because I installed Node.js into the folder C:\applications (not the default one, which is C:\Program Files\nodejs)

It's strange, but after re-installing Node.js into the default location I can successfully run npm install on my freshly cloned project.

Solution 11:[11]

The internal module pattern

try this example to solve circular dependency. details you can find Here

// -- app.js --
import { AbstractNode } from './internal'

/* as is */

// -- internal.js --
export * from './AbstractNode'
export * from './Node'
export * from './Leaf'

// -- AbstractNode.js --
import { Node, Leaf } from './internal'

export class AbstractNode {
   /* as is */
}

// -- Node.js --
import { AbstractNode } from './internal'

export class Node extends AbstractNode {
   /* as is */
}

// -- Leaf.js --
import { AbstractNode } from './internal'

export class Leaf extends AbstractNode {
   /* as is */
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 ajxs
Solution 3
Solution 4 InsOp
Solution 5 PeS
Solution 6 Wand Maker
Solution 7 Marvin Scharle
Solution 8 Alucard
Solution 9
Solution 10 Vitaly Sazanovich
Solution 11 9me