39

I'm working in typescript 1.5 in visual studio. I have a main class called app.ts, and another called FizzBuzzManager.ts. I can't figure out what is wrong with this code, but it outputs the error, "TypeError: jim.FizzBuzzManager 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();

};

FizzBuzzManager.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");
}

}

The output when looking at the compiled output in a browser is this:

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
5
  • what version of es are you transpiling to? Commented Jan 3, 2016 at 22:03
  • Please add your transpiled script (i.e. the .js file used by your browser). Commented Jan 3, 2016 at 22:08
  • Target javascript version is ES5. Commented Jan 3, 2016 at 22:34
  • It is working fine in ES5 for me... But I am getting the "not a constructor" error in ES6... But how far is the namespace usage good? Commented May 31, 2016 at 19:07
  • I have the same problems with typescript. I inherit old projects that use different flavors of exports/require and they seem to only work with a very specific set of compile options. It's very difficult to reverse engineer by looking at old typescript what the exact options are needed to compile it. Commented Oct 29, 2021 at 15:45

18 Answers 18

27

TypeError: jim.FizzBuzzManager is not a constructor

This is a common error when you use --out : https://basarat.gitbook.io/typescript/main-1/outfile

You are responsible for loading the files in the right order. Don't use out and use external modules 🌹

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you. I wasn't loading things in the correct order. That was my issue with this error.
The link is broken
...loading and exporting in the right order! Thanks! :)
what is --out? I'm not using this and I'm getting this behavior error.
19

When migrating from plain ES6 / Node.js using module.exports/require() it often happens to me that I forget to remove the old module.exports = <class> which also causes this error.

3 Comments

Awww, snap. I spent a couple of hours trying to figure this out. This was it! Never scrolled down to the end of the file. Lol. You'd think maybe tsc would complain/warn if a .ts file had a "module.exports = " in it perhaps. THANKYOU.
exactly the same here as the poster abover. MANY THANKS!
You may also be able to solve the problem by adding "esModuleInterop": true to your tsconfig.json file.
12

I came upon this question after googling "typescript is not a constructor". Unfortunately, these answers did not resolve my problem. I eventually found the solution, so I am posting it here for posterity.

Problem

I defined the following TypeScript class:

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

I then called the class in a separate module:

module mymodule.test {

    var myClass = new mymodule.myclass();

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

After compiling and while attempting to load the page that executes the resulting Javascript, the page wouldn't load properly and I saw the following JS exception:

Uncaught TypeError: mymodule.myclass is not a constructor

Solution

A fellow developer was kind enough to point out that I needed to move the instantiation of the object inside of my function. So now my instantiation code looks like this and it works as it should:

module mymodule.test {

    var myClass: mymodule.myclass;

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

1 Comment

Why is this necessary?
9

In my case it was just circular dependencies. Take a look at that because this one is hard to catch

1 Comment

If this error "suddenly" happens and the constructor was working correctly beforehand, this is most likely due to a new import causing a circular dependency. I was constructing an object at the top level of a module in a circular dependency with the declaration of the class.
6

I had this error my_imported_module_1.MyModule is not a constructor.

I was using the approach when I got this error: import { MyModule } from 'my-module-sdk';

but I got it to work when I changed it to this approach: const MyModule = require('my-module-sdk');

In my tsconfig.json, I have "target" set to "es5", and tried changing it "es6" and that still didn't help.

Here are some of my other tsconfig options:

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

Comments

5

It might be helpful to think about it as if you were writing the code in JavaScript directly. I came across this question because I got the same error in an Angular 2 test spec written in TypeScript. After thinking about it based on the answers above, I realized that JavaScript would have no idea what my equivalent to your BuzzFeed class was because it was at the bottom of the file.

I moved the class up to the top of the file before my first describe statement and everything works. Thought this might help others like myself.

Comments

5

Make sure that class definition is declared before its usage. That was the solution for my problem.

Correct:

class Foo {...}
...
const foo = new Foo();

Incorrect:

const foo = new Foo();
...
class Foo {...}

Comments

4

I think you're doing:

export class Something

Change it to this and it will work

export default class Something

4 Comments

why does this matter?
this helped with the issue I had, not adding it means you have more than one class in that file and you are trying to call one of them
It doesn't matter as long as you import it correctly, if you are using default exports, then you should be importing it this way: import Something from 'lib' for non-default export, we simply need braces: import { Something } from 'lib'. I don't think that it's error related
in my case I had two classes in one file and an import import { ClazzName } from 'lib' and still getting the error; after splitting into multiple files OR adding default to one of the classes - it solved the problem; I'm using yarn workspaces if this makes any difference and I got a feeling it does 🤔
3

Which typescript version do you use?

There is a Bug in tsc 1.8.10:

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

Comments

3

This error message means that [Class] is not initialized by the time a call to its constructor is made.

Unlike functions, classes are not “hoisted” to the top of the scope they are declared in. Whenever code uses a class that is declared later (i.e. down below in the file), this error appears.

Solution: reorganize your code so that call sites for a class appear below that class' definition in the source code.

Comments

2

I tried to repeat your problem and I did not find any error:

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();

    };
}

FizzBuzzManager.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");
}

}

Then

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

and compiled app.js file looks like this:

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 browser reports in its console:

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

There is a good explanation of the error you are getting here: Javascript: TypeError: ... is not a constructor (not that it reveals the origin of the problem but you may see the problem in your transpiled code.)

8 Comments

Thanks, but how do I find the tsc file path?
I installed it via npm install [email protected] in my command line
This install TypeScript in your current working directory, so you can try it out very easily.
I installed it from npm, but I'm still getting the error. Are you putting this compiler argument in the textfield labeled "conditional compilation symbols" under project->Properties->Build?
Even when I enter the whole line in command line, it says, "C:\Users\James\nodey-node\tsc is not a recognized internal or external command, operable program, or batch file"
|
2

For future readers, the problem could also be if the constructor expects parameters and you are giving no parameters or a different number of parameters. This is because for Javascript a function with a different number of parameters is a different function.

A simple solution could be to add default parameters in the constructor.

My example was like this:

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
//...

The solution here was either to use default parameter in the constructor or to pass the scoping object in the usage of the constructor

1 Comment

I'll add that it can also happen if the constructor is outright missing. This happened to me when a third party library was using another third party library (AWS CDK) that had moved stuff around between libraries.
2

Using export = Something instead of export class Something solved it for me.

Comments

1

In my case I had the problem when I used babel with preset-env to compile TS-sources.

Works:

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

Wrong:

{
    "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"]
}

1 Comment

Nice, that helped me fixing my error. But how do we use babel-env then?
1

at first, make sure that use

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

to refrence code to another .ts file at typescript root file

to compile typescript files that exist in different file.ts use this command

tsc --out app.js app.ts

because this command converts all typescript files into app.js

Comments

1

TL;DR

Clear the output directory

Explanation

In my case, this problem occurred after I had moved src/email.ts to src/email/index.ts. TSC didn't remove lib/email.ts, causing the class I had defined in the new location not to be available.

Comments

1

I had same issue, apart from export default class Something I created a separate file called something.ts then another file index.ts in the someting.ts file I had

export default class Something {}

then in index.ts I wrote

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

after that I could import as (For Typescript)

import Something from './';

and as (For Javascript)

const Something = require('./');

Comments

0

With JetBrains WebStorm, it's possible to get this error in your tests even if you have fixed a problem with imports in the code itself.

e.g. the following fix:

// import { Foo } from '@foo/bar';

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

solved the issue, but it was necessary to run npm run compile or npm run test afterwards.

Then running the tests in WebStorm worked as expected.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.