【问题标题】:Why Does This Typescript Output "[Class] is not a constructor."?为什么此 Typescript 输出“[Class] 不是构造函数。”?
【发布时间】:2016-04-07 12:12:29
【问题描述】:

我正在 Visual Studio 中使用 typescript 1.5。我有一个名为 app.ts 的主类,还有一个名为 FizzBu​​zzManager.ts 的主类。我无法弄清楚这段代码有什么问题,但它会输出错误“TypeError: jim.FizzBu​​zzManager is not a constructor”。

app.ts

 namespace jim {
    class Greeter {
        element: HTMLElement;
        span: HTMLElement;
        timerToken: number;

        constructor() {
            window.console.log("constructing Greeter.");
            this.init();
        }

        private init() {
            window.console.log("Calling init.");
            var _fizzBuzzManager: any = new jim.FizzBuzzManager();
    }

}

    window.onload = () => {
        window.console.log("Hello")
        var greeter = new Greeter();

};

FizzBu​​zzManager.ts

namespace jim {

export class FizzBuzzManager {

    constructor() {
        window.console.log("Making a FizzBuzzManager.");
    }

    public myThing: String = "Hi";

    public fizzBuzz2() {
        window.console.log("fizzbuzzing2 " + this.myThing);
    }

}

export function fizzBuzz() {
    window.console.log("export function fizzbuzz");
}

}

在浏览器中查看编译输出时的输出是这样的:

Hello                                                  app.js:15:9 
constructing Greeter.                                  app.js:5:13 
Calling init.                                          app.js:9:13 
TypeError: jim.FizzBuzzManager is not a constructor    app.js:10:36

【问题讨论】:

  • 你要转成什么版本的es?
  • 请添加您的转译脚本(即您的浏览器使用的.js文件)。
  • 目标 javascript 版本是 ES5。
  • 它在 ES5 中对我来说运行良好...但我在 ES6 中收到“不是构造函数”错误...但是命名空间的使用情况有多好?
  • 我在使用 typescript 时遇到了同样的问题。我继承了使用不同风格的 export/require 的旧项目,它们似乎只适用于一组非常特定的编译选项。通过查看旧的打字稿来进行逆向工程非常困难,编译它需要哪些确切的选项。

标签: typescript


【解决方案1】:

TypeError: jim.FizzBu​​zzManager 不是构造函数

这是您使用 --out 时的常见错误:https://basarat.gitbook.io/typescript/main-1/outfile

您有责任按正确的顺序加载文件。不要使用out并使用外部模块?

【讨论】:

  • 谢谢。我没有按正确的顺序加载东西。这是我遇到此错误的问题。
  • 链接失效
  • ...以正确的顺序加载和导出!谢谢! :)
【解决方案2】:

我在谷歌搜索“打字稿不是构造函数”后遇到了这个问题。不幸的是,这些答案并没有解决我的问题。我最终找到了解决方案,因此我将其发布在这里以供后代使用。

问题

我定义了以下 TypeScript 类:

module mymodule {
    export class myclass {
        addDocuments(parentId: string) {
        // Code removed for brevity...
        }
    }
}

然后我在一个单独的模块中调用该类:

module mymodule.test {

    var myClass = new mymodule.myclass();

    export function initialize(): void {
        myClass.addDocuments("test123");
    }
}

编译后并尝试加载执行结果 Javascript 的页面时,页面无法正确加载,我看到以下 JS 异常:

未捕获的类型错误:mymodule.myclass 不是构造函数

解决方案

一位开发人员非常友好地指出我需要将对象的实例化移动到我的函数中。所以现在我的实例化代码看起来像这样,它可以正常工作:

module mymodule.test {

    var myClass: mymodule.myclass;

    export function initialize(): void {
        myClass = new mymodule.myclass();
        myClass.addDocuments("test123");
    }
}

【讨论】:

  • 为什么有必要这样做?
【解决方案3】:

当使用 module.exports/require() 从纯 ES6 / Node.js 迁移时,我经常会忘记删除旧的 module.exports = <class>,这也会导致此错误。

【讨论】:

  • 哇,快。我花了几个小时试图弄清楚这一点。就是这样!从不向下滚动到文件的末尾。哈哈。如果 .ts 文件中可能包含“module.exports =”,您可能会认为 tsc 可能会抱怨/警告。谢谢。
【解决方案4】:

将其视为直接用 JavaScript 编写代码可能会有所帮助。我遇到了这个问题,因为我在用 TypeScript 编写的 Angular 2 测试规范中遇到了同样的错误。在根据上面的答案思考之后,我意识到 JavaScript 不知道我的 BuzzFeed 类的等价物是什么,因为它位于文件的底部。

在我的第一个描述语句之前,我将类移到了文件的顶部,一切正常。认为这可能会帮助像我这样的其他人。

【讨论】:

    【解决方案5】:

    您使用哪个打字稿版本?

    tsc 1.8.10 有一个Bug:

    https://github.com/Microsoft/TypeScript/issues/8910

    【讨论】:

      【解决方案6】:

      此错误消息表示 [Class] 在调用其构造函数时尚未初始化。

      Unlike functions,类没有“提升”到声明它们的作用域的顶部。只要代码使用稍后声明的类(即文件下方),就会出现此错误。

      解决方案:重新组织您的代码,使某个类的调用站点出现在源代码中该类的定义下方。

      【讨论】:

        【解决方案7】:

        我尝试重复您的问题,但没有发现任何错误:

        app.ts

        namespace jim {
            class Greeter {
                element: HTMLElement;
                span: HTMLElement;
                timerToken: number;
        
                constructor() {
                    window.console.log("constructing Greeter.");
                    this.init();
                }
        
                private init() {
                    window.console.log("Calling init.");
                    var _fizzBuzzManager: any = new jim.FizzBuzzManager();
                }
        
            }
        
            window.onload = () => {
                window.console.log("Hello")
                var greeter = new Greeter();
        
            };
        }
        

        FizzBu​​zzManager.ts

        namespace jim {
        
        export class FizzBuzzManager {
        
            constructor() {
                window.console.log("Making a FizzBuzzManager.");
            }
        
            public myThing: String = "Hi";
        
            public fizzBuzz2() {
                window.console.log("fizzbuzzing2 " + this.myThing);
            }
        
        }
        
        export function fizzBuzz() {
            window.console.log("export function fizzbuzz");
        }
        
        }
        

        然后

        c:\Work\TypeScript-playground>node_modules\.bin\tsc --out app.js app.ts FizzBuzzManager.ts
        

        编译后的 app.js 文件如下所示:

        var jim;
        (function (jim) {
            var Greeter = (function () {
                function Greeter() {
                    window.console.log("constructing Greeter.");
                    this.init();
                }
                Greeter.prototype.init = function () {
                    window.console.log("Calling init.");
                    var _fizzBuzzManager = new jim.FizzBuzzManager();
                };
                return Greeter;
            })();
            window.onload = function () {
                window.console.log("Hello");
                var greeter = new Greeter();
            };
        })(jim || (jim = {}));
        var jim;
        (function (jim) {
            var FizzBuzzManager = (function () {
                function FizzBuzzManager() {
                    this.myThing = "Hi";
                    window.console.log("Making a FizzBuzzManager.");
                }
                FizzBuzzManager.prototype.fizzBuzz2 = function () {
                    window.console.log("fizzbuzzing2 " + this.myThing);
                };
                return FizzBuzzManager;
            })();
            jim.FizzBuzzManager = FizzBuzzManager;
            function fizzBuzz() {
                window.console.log("export function fizzbuzz");
            }
            jim.fizzBuzz = fizzBuzz;
        })(jim || (jim = {}));
        

        Chrome 浏览器在其控制台中报告:

        app.js:15 Hello
        app.js:5 constructing Greeter.
        app.js:9 Calling init.
        app.js:24 Making a FizzBuzzManager.
        

        您在这里遇到的错误有一个很好的解释:Javascript: TypeError: ... is not a constructor(不是说它揭示了问题的根源,但您可能会在您的转译代码中看到问题。)

        【讨论】:

        • 谢谢,但是如何找到 tsc 文件路径?
        • 我在命令行中通过npm install typescript@1.5 安装了它
        • 这会将 TypeScript 安装在您当前的工作目录中,因此您可以非常轻松地尝试一下。
        • 我从 npm 安装了它,但我仍然收到错误消息。您是否将此编译器参数放在 project->Properties->Build 下标记为“条件编译符号”的文本字段中?
        • 即使我在命令行中输入整行,它也会显示“C:\Users\James\nodey-node\tsc 不是可识别的内部或外部命令、可运行程序或批处理文件"
        【解决方案8】:

        对于未来的读者,问题也可能是构造函数是否需要参数 并且您没有提供任何参数或不同数量的参数。 这是因为对于 Javascript,具有不同数量参数的函数是不同的函数。

        一个简单的解决方案是在构造函数中添加默认参数。

        我的例子是这样的:

        SegmentsQueryBuilder.ts

        class SegmentsQueryBuilder {
          //...
          constructor(scoping) {
            //...
          }
        //...
        }
        

        segments.query.builder.test.ts

        describe('Segment base query', () => {
          test('should create segment select with default fields', () => {
            const segmentQueryBuilder = new SegmentQueryBuilder() //ERROR HERE
        //...
        

        这里的解决方案是要么在构造函数中使用默认参数,要么在构造函数的使用中传递作用域对象

        【讨论】:

        • 我要补充一点,如果构造函数完全丢失,也会发生这种情况。当第三方库使用另一个在库之间移动内容的第三方库 (AWS CDK) 时,我发生了这种情况。
        【解决方案9】:

        我遇到了这个错误my_imported_module_1.MyModule is not a constructor

        当我收到此错误时,我正在使用该方法: import { MyModule } from 'my-module-sdk';

        但是当我将其更改为这种方法时,我得到了它: const MyModule = require('my-module-sdk');

        在我的 tsconfig.json 中,我将“target”设置为“es5”,并尝试将其更改为“es6”,但仍然没有帮助。

        这是我的一些其他 tsconfig 选项:

        "target": "es5",
        "module": "esnext",
        "declaration": true,
        "rootDir": "./src",
        "moduleResolution": "node",
        "lib": ["es6", "dom", "es2016", "es2017", "es2018", "es2019", 
        "es2020"],
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "allowJs": false
        

        【讨论】:

          【解决方案10】:

          就我而言,当我使用 babel 和 preset-env 编译 TS-sources 时遇到了问题。

          作品:

          {
              "presets": ["@babel/typescript"],
              "plugins": [
                  "@babel/proposal-class-properties",
                  "@babel/proposal-object-rest-spread",
                  "@babel/plugin-transform-runtime"
              ],
              "ignore": ["node_modules", "src/test"]
          }
          

          错误:

          {
              "presets": [
                  "@babel/typescript",
                  [
                      "@babel/preset-env",
                      {
                          "targets": {
                              "browsers": [
                                  "last 2 Chrome versions",
                                  "last 1 Safari versions",
                                  "last 1 Firefox versions"
                              ]
                          }
                      }
                  ]
              ],
              "plugins": [
                  "@babel/proposal-class-properties",
                  "@babel/proposal-object-rest-spread",
                  "@babel/plugin-transform-runtime"
              ],
              "env": {
                  "node": {
                      "presets": [
                          [
                              "@babel/preset-env",
                              {
                                  "targets": {
                                      "esmodules": true,
                                      "node": "current"
                                  },
                                  "modules": "auto"
                              }
                          ]
                      ]
                  }
              },
          
              "ignore": ["node_modules", "src/test"]
          }
          

          【讨论】:

          • 很好,这帮助我解决了我的错误。但是我们如何使用 babel-env 呢?
          【解决方案11】:

          首先,确保使用

          /// <reference path = "FizzBuzzManager.ts" />   
          

          将代码引用到打字稿根文件中的另一个 .ts 文件

          要编译存在于不同 file.ts 中的 typescript 文件,请使用此命令

          tsc --out app.js app.ts

          因为这个命令会将所有 typescript 文件转换成 app.js

          【讨论】:

            【解决方案12】:

            我认为你在做:

            export class Something
            

            改成这个就可以了

            export default class Something
            

            【讨论】:

            • 为什么这很重要?
            • 这有助于解决我遇到的问题,不添加它意味着您在该文件中有多个类并且您正在尝试调用其中一个
            【解决方案13】:

            使用export = Something 而不是export class Something 为我解决了这个问题。

            【讨论】:

              【解决方案14】:

              使用 JetBrains WebStorm,即使您在代码本身中修复了导入问题,也可能在测试中出现此错误。

              例如以下修复:

              // import { Foo } from '@foo/bar';
              
              import Foo = require('@foo/bar);
              

              解决了这个问题,但之后需要运行npm run compilenpm run test

              然后在 WebStorm 中运行测试按预期工作。

              【讨论】:

                【解决方案15】:

                TL;DR

                清空输出目录

                说明

                就我而言,这个问题是在我将src/email.ts 移动到src/email/index.ts 之后发生的。 TSC 没有删除lib/email.ts,导致我在新位置定义的类不可用。

                【讨论】:

                  【解决方案16】:

                  我有同样的问题,除了export default class Something 我创建了一个名为 something.ts 的单独文件,然后创建了另一个文件 index.tssometing.ts 文件中 我有

                  export default class Something {}
                  

                  然后在index.ts 我写了

                  import { Something } from './something';
                  export = Something;
                  

                  之后我可以导入为(对于 Typescript)

                  import Something from './';
                  

                  和 as(对于 Javascript)

                  const Something = require('./');
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-10-12
                    • 2017-12-09
                    • 2014-03-12
                    • 2018-12-09
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-10-22
                    相关资源
                    最近更新 更多