TypeError:类扩展未定义的值不是函数或null


78

尝试创建这些实体时出现以下错误。

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

我假设这与循环依赖关系有关,但是在使用表继承和一对多关系时应该如何避免呢?

在抱怨以下javascript BaseComic_1.BaseComic

let Variant = class Variant extends BaseComic_1.BaseComic {

这是完整的文件。

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

Answers:


123

我有同样的问题。事实证明,我是循环导入类,这显然是一个限制。(请参阅以下GitHub问题:#20361#4149#10712

请注意,循环引用似乎在文件之间也受到限制,而不仅仅是类型。

这个其他答案


1
我在browserify中遇到了循环导入问题。这是不一致且奇怪的-修改文件或注释并删除内容并重新运行有时会使其消失。整rick
user1978019

6
请注意,循环引用似乎是在文件之间,而不仅仅是类型之间。因此,即使当你的类型的引用不是圆形的,你可能仍然有因.TS这个问题的文件你的类型方式支付。
barfuin

2
@JoshuaKing您可以链接到有关打字稿中cirtualr导入类的“限制”的资源吗?
布鲁诺·比耶里

1
根据我的经验,进口顺序也很重要。我有一个用户实体和另外两个具有相同抽象类的实体。其他2个实体也导入了User,只要抽象类是最后一次导入(主要是在user之后),一切都很好。我以另一种方式订购进口商品后,申请便告破裂。
Tobias Stangl

1
@BrunoBieri不是Typescript的限制。这是运行时错误-模块解析器无法在循环导入中进行导航。我发现的一个很好的资源是《您不懂JS》
gombosg

17

正如上面的Thomas Jensen的评论所指出的,循环引用不仅可以在Types中发生,而且可以在文件中发生。当我从同一文件导出基本类型和派生类型时,我遇到了同样的问题。如:

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

这是容易陷入的陷阱。将其发布在这里,希望可以节省其他调试时间。


因此,当您拥有这样的索引文件时,最好的解决方法是什么。您将基础文件放在哪里?还是某种反模式的索引文件
Jonathan

我认为index.ts文件不是反模式,我知道有些人不同意这一点。我认为它们是向模块提供有用的公共接口的好方法。从内存中,我最终通过重构解决了这个问题,根本不需要导出基类。不幸的是,我不能给你一个更好的答案。
ajxs

2

刚遇到这个问题,那很奇怪。我正在运行该项目

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

而且即使我按照公认的答案建议删除了循环引用后,上述错误仍然失败。

但是,如果我运行tsc它,则可以正常编译,即使使用,它也可以正常运行--require ts-node/register...

希望这对某人有帮助。


2

循环依赖性可能很难识别。迈克尔·韦斯特斯特(Michael Weststrate)对循环依赖有一个有趣的阅​​读,并提出了一种解决它们的模式。

自动循环依赖检测。

Madge不仅可以使用允许扩展的模式,还可以使用一种超级有用的工具,只需很少的工作即可为您识别循环依赖项。

Madge可以运行.ts.js归档。我发现在两个目录中运行它很有用,因为由于编译过程它们可能会给出不同的结果。

对于.js文件:madge --circular --extensions ts <directory_path>

对于.ts文件:madge --circular <directory_path>


0

我来到这里是因为当开玩笑地执行代码时,它引发了此错误。这是因为写的时候moduleNameMapperjest.config.js对象中的元素的顺序是至关重要的。

有一个帮助程序可以从中导入模块名称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>/' } */ )
};

摘自ts-jest官方文档


0

我遇到了同样的问题,因为我的编辑器是Entity从错误的软件包中自动导入的。

一旦我改import { Entity } from 'typeorm/decorator/entity/Entity';回到import { Entity } from 'typeorm';错误消息消失了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.