【问题标题】:Typescript error runtime error: Cannot read property 'prototype' of undefined when extending打字稿错误运行时错误:扩展时无法读取未定义的属性“原型”
【发布时间】:2017-11-15 02:31:33
【问题描述】:

所以我在控制台中收到上述错误。这是因为_super 在传递给__extends 时未定义(在生成的.js 中)。

这里有一些可以用来重现错误的测试代码:

//This is the entirety of the file Test.ts
module Test {
    export class Test1 {
        public Name: string;
        public Number: number;

        constructor() {

        }
    }
}

然后在一个单独的文件中,我有一个继承自该文件的类:

/// <reference path="Test.ts" />
module Test {
    export class Test2 extends Test1 {
        constructor() {
            super();
        }
    }
}

&lt;reference path... 应该不需要(现在也不需要),但我添加了它以查看它是否有帮助(它没有)。

文件通过BundleConfig 以正确的顺序(Test.ts 然后Test2.ts)包含(运行有或没有优化都没有任何效果)。

我可能是个大菜鸟,但我一点也不知道我搞砸了什么。我在网上发现的所有其他这个问题的实例都是来自使用命令行编译器将多个 Typescript 文件组合成一个文件的人。我正在使用捆绑器来执行此操作,但即使我不合并它们,我也会遇到完全相同的问题。

请帮帮我,我无能为力!

根据要求,这是编译后的 javascript: 测试.js:

//This is the entirety of the file Test.ts
var Test;
(function (Test) {
    var Test1 = (function () {
        function Test1() {
        }
        return Test1;
    })();
    Test.Test1 = Test1;
})(Test || (Test = {}));
//# sourceMappingURL=Test.js.map

Test2.js:

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
/// <reference path="Test.ts" />
var Test;
(function (Test) {
    var Test2 = (function (_super) {
        __extends(Test2, _super);
        function Test2() {
            _super.call(this);
        }
        return Test2;
    })(Test.Test1);
    Test.Test2 = Test2;
})(Test || (Test = {}));
//# sourceMappingURL=Test2.js.map

【问题讨论】:

  • 我在午餐时重新启动了我的电脑,现在它可以工作了。多么奇怪。

标签: javascript visual-studio asp.net-mvc-4 typescript


【解决方案1】:

发生这种情况的可能原因:

  1. 四重检查BundleConfig 是否以正确的顺序连接文件。到目前为止,这是导致该错误的最常见原因。
  2. 验证您在Test.ts 中没有任何顶级export 指令。这会导致文件成为外部模块,Test1 将不再可见。

否则,您应该将发出的 JavaScript 发布到问题中,以便我们诊断导致问题的原因。

【讨论】:

  • BundleConfig 仅在发布模式下连接文件,但无论哪种方式,代码的顺序都是正确的(我什至尝试手动包含已编译的 .js 文件以 100% 确定)。我在上面发布了我的全部.ts 文件(我遇到了更复杂代码的错误,所以我只使用上面的打字稿创建了一个新页面)。我将对.js 文件做同样的事情。
  • HTML页面上的script标签的顺序是什么?您是否在网页中设置了断点以查看何时分配?
  • 来自页面的HTML:&lt;script type="text/javascript" src="/js/@jsFolder/Home/Test.js"&gt;&lt;/script&gt;&lt;script type="text/javascript" src="/js/@jsFolder/Home/Test2.js"&gt;&lt;/script&gt;我没有在网页中设置断点。我会在午饭后试试(现在是时候)了。
  • 这为我指明了解决相同问题的正确方向。
  • 这对我也有帮助。对于那些使用多级继承将所有类都放在一个文件中的人,请确保它们在文件中按层次顺序排列。例如,如果您有 abstract class Human -> abstract class Homo extends Human -> class Sapien extends Homo,那么文件中的类定义需要以相同的顺序排列:Human,Homo,然后是 Sapien。
【解决方案2】:

今天发生了这个错误。不知道什么是 OP 场景,但在我的团队中,我们有:

  1. TypeScript v1.8.10
  2. 基于 Webpack 的开发构建,具有连接、源映射、无优化/丑化
  3. Angular 2 依赖注入
  4. 在同一文件中定义的基类和派生类(例如,dependencies.ts
  5. 派生类之后定义的基类
  6. 没有编译错误或警告
  7. 控制台日志显示Uncaught TypeError: Cannot read property 'prototype' of undefined
  8. 调用堆栈指向另一个类的最后一行的内部 __extends 函数,在另一个文件(比如 client.ts)中,将它们作为依赖项导入

在代码中:

// dependencies.ts

import { Injectable } from 'angular2/core';

@Injectable()
export class LocalStorageService extends BaseStorageService {
  constructor() {
    super(localStorage);
  }
}

class BaseStorageService {
  constructor(private storage: Storage) {}
  // ...
}

和:

// client.ts

import { Injectable } from 'angular2/core';
import { LocalStorageService } from './dependencies';

@Injectable()
export class AuthStorageService {

  constructor(private permanentStorage: LocalStorageService) { }
  // ...

} // <-- call stack pointed here with inner '__extends' function

通过派生类之前定义基类解决了问题。经过快速搜索和阅读后,这似乎与已知(且未解决?)TypeScript 问题有关,例如#21#1842

HTH

【讨论】:

  • 正如上面所说,我遇到的问题是某种奇怪的问题,通过重新启动我的电脑得到了解决。我的问题中的代码是我用来产生错误的代码 - 但代码和设置应该不会产生错误:)。
  • 是的,我读到了,这就是为什么我不确定这是不是同样的场景。但是错误是相同的,其他人由于定义了订单类而遇到了该错误。对于通过谷歌搜索来到这里的人(比如我)可能会有所帮助
  • 很好的描述!对我来说,我有一个在基类之前定义的 UNUSED 类。所以这个问题实际上比你描述的更普遍。
  • 我在使用 Typescript 的 ionic2 项目中遇到了类似的问题。进行导入的一种常见方法是将它们收集在一个充满导出的 ts 文件中。这就是我们的问题的原因,因为它包含基类和子类的导出,这不知何故弄乱了导入的顺序。解决方案是将基类从中拉出(我们也将其移到另一个文件夹中)并从该文件中显式导入基类。我们还有一个泛型类型的类,它使用这个基类作为它的类型参数,所以我们的错误出现在使用这个泛型类的类中。
【解决方案3】:

HTML 上的脚本顺序很重要。

假设你有一个 TypeScript 文件A.ts,它定义了一个抽象类 和一个文件B.ts,其类扩展了 A.ts 中的抽象类

导出抽象类 ShipmentsListScope 实现 IShipmentsListScope {

A.ts:

module app.example{
  "use strict";

  interface IMyInterface{
    // ..
  } 
  export abstract class MyAbstract implements IMyInterface{
    // ..
  }
}

B.ts

module app.example{
    "use strict";

  class MyChildClass extends MyAbstract {
    // ...
  }
}

那么在您的 HTML 中,一旦生成了 javascript,您必须确保脚本的顺序是正确的:

<script src="/app/example/A.js"></script> <!-- A.js BEFORE -->
<script src="/app/example/B.js"></script>

【讨论】:

    【解决方案4】:

    我遇到了同样的问题,它是由export default 语句引起的。为了修复它,我只是删除了这些并以另一种方式导入了所需的项目:

    之前

    A.ts

    export default MyClass;
    
    class MyClass { ... }
    

    B.ts

    import MyClass from "./A";
    
    class MyClass2 extends MyClass { ... }
    

    之后

    A.ts

    export class MyClass { ... }
    

    B.ts

    import { MyClass } from "./A";
    
    class MyClass2 extends MyClass { ... }
    

    【讨论】:

      【解决方案5】:

      就离开这里我是如何为我的案例解决这个问题的:我错过了 TS 文件顶部的引用,构建完全没问题,而我在运行时遇到了同样的错误。添加似乎是可选的引用解决了我的运行时问题。

      【讨论】:

      • @Samuel A /// &lt;reference /&gt; 到我在项目中创建的 ts 文件
      猜你喜欢
      • 2018-10-26
      • 2020-01-24
      • 1970-01-01
      • 1970-01-01
      • 2021-10-18
      • 2019-03-13
      • 2017-04-30
      • 1970-01-01
      • 2020-07-12
      相关资源
      最近更新 更多