3
votes

I've found a strange bug.

If you have two classes in different files, and for example class B extends class A, and class A has a variable typed B, TypeScript compiles in wrong order with --out main.js command (when you compile whole project into one file). Wrond order results that javascript throws an error: Uncaught TypeError: Cannot read property 'prototype' of undefined This is because class B is earlier in the code than A, and it want to use it.

Here is the simpliest example:

A.ts

///<reference path='B.ts'/>

class A
{
    public b: B;

    constructor()
    {
    }

    init()
    {
        this.b=new B();
    }
}

B.ts

///<reference path='A.ts'/>
class B extends A
{
    constructor()
    {
        super();
    }
}

app.ts

///<reference path='A.ts'/>
var a: A=new A();
a.init();

Generated main.js

var __extends = this.__extends || function (d, b) {
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var B = (function (_super) {
    __extends(B, _super);
    function B() {
        _super.call(this);
    }
    return B;
})(A);
var A = (function () {
    function A() {
    }
    A.prototype.init = function () {
        this.b = new B();
    };
    return A;
})();
var a = new A();
a.init();
//@ sourceMappingURL=main.js.map

Is there a workaround?

2

2 Answers

1
votes

I'm not sure about your circular dependencies. If you want to substitute the classes then the dependencies really ought to be in one direction. Here is an example:

class A {
    constructor(public b: A)
    {
    }
}

class B extends A
{
    constructor()
    {
        super(this);
    }
}

var a = new A(new B());
var b = new B();

Now Your "b.ts" file only needs to depend on the "a.ts" file - not the other way around. Because B extends A, you can pass in an instance of B when you create a new A. Because the dependency is one-directional, TypeScript now has a chance of compiling things in the right order.

Here is a picture to show the dependency issue:enter image description here

0
votes

Use the export statement on the declared typescript module or class or interface, then you can import the desired function, class or whatever. Typescript is throwing an error because the variable you are trying to reference does not exist.

For example:

module API {
    export class Main {
        public name: string;
        public interest: string;

        constructor() {
            this.name = "Someone";
            this.interest = "web technology";
        }

        puts() {
            console.log(this.name, " like", this.interest);
        }
    }
}

..and then you can call the desired function.

import API;
var c = new API.Main();