When working with a specific setup in TypeScript, I encountered a situation where at runtime in JavaScript, I ended up with empty class objects. This occurred when two classes referenced each other, leading to one of them being empty within the scope of the other. While I know how to address this issue by introducing a third class between the two, I am curious as to why it happens and whether there is a way to maintain cross-references while ensuring functional code. After experimenting with various setups, here are my findings:
Setup: each class in its own module (module names and class names are irrelevant) ClassA serves as our main entry point:
// ClassA
import ClassB = require('ClassB');
import ClassC = require('ClassC');
class ClassA
{
constructor()
{
console.log(ClassC.TEST);// displays 1
new ClassB();// displays null
console.log(ClassC.TEST);// displays 1
}
}
export = ClassA;
// ClassB (in different module)
import ClassC = require('ClassC');
class ClassB
{
public static ClassBRef:any;
constructor()
{
console.log(ClassC.TEST);// in this context, ClassC is an empty object without any properties
}
}
export = ClassB;
// ClassC (in different module)
import ClassB = require('ClassB');
class ClassC
{
public static TEST:number = 1;
constructor()
{
ClassB.ClassBRef;
}
}
export = ClassC;
Due to the mutual references between ClassB and ClassC, the behavior is such that ClassC exists without issues within the scope of ClassA, but appears as an empty object without properties within the scope of ClassB during runtime in JavaScript. While everything functions correctly in TypeScript, the problem arises in JavaScript. Despite trying various modifications like changing module names, locations, class names, using static or instance scopes, constructors, instance methods, or static methods, the result remains consistent - ClassC is always empty within the scope of ClassB.
Although implementing a third class to handle communication between the two problematic classes resolves the issue (ensuring one of them has no direct reference to the other), I still wonder if there is a way to achieve this without relying on a third class and without eliminating the cross-reference between the two classes?