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

JavascriptTypescriptTypeorm

Javascript Problem Overview


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;
}

Javascript Solutions


Solution 1 - Javascript

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 - Javascript

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 - Javascript

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 - Javascript

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 - Javascript

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 - Javascript

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 - Javascript

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 - Javascript

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 9 - Javascript

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 - Javascript

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 11 - Javascript

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 */
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionprolink007View Question on Stackoverflow
Solution 1 - JavascriptJoshua KingView Answer on Stackoverflow
Solution 2 - JavascriptajxsView Answer on Stackoverflow
Solution 3 - JavascriptJesusIniestaView Answer on Stackoverflow
Solution 4 - JavascriptInsOpView Answer on Stackoverflow
Solution 5 - JavascriptPeSView Answer on Stackoverflow
Solution 6 - JavascriptWand MakerView Answer on Stackoverflow
Solution 7 - JavascriptMarvin ScharleView Answer on Stackoverflow
Solution 8 - JavascriptVitaly SazanovichView Answer on Stackoverflow
Solution 9 - JavascriptJeremy ThompsonView Answer on Stackoverflow
Solution 10 - JavascriptAlucardView Answer on Stackoverflow
Solution 11 - Javascript9meView Answer on Stackoverflow