Typescript Class Getting Vacant

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?

Answer №1

Dealing with a circular reference between ClassB and ClassC in JavaScript environments can be quite challenging.

There are two main scenarios to consider:

ClassB is required. ClassC is required. ClassC tries to require ClassB.

In this situation, if ClassB is still being constructed (without exporting anything), it will result in an undefined value. The opposite effect occurs if ClassC is loaded first.

Although there is a way to resolve this issue without additional files, the approach may not feel entirely right.

import containerC = require('ClassC');
// or import * as containerC from 'ClassC'; in ES6 syntax

export class ClassB
{
    public static ClassBRef:any;

    constructor()
    {
        console.log(containerC.ClassC.TEST);// in this scope ClassC is an empty object with no properties
    }
}

// ClassC
import containerB = require('ClassB');

export class ClassC
{
    public static TEST:number = 1;

    constructor()
    {
        containerB.ClassB.ClassBRef;
    }
}

This solution works because the return value from require will be filled by the time either class's constructor runs.

It's important to note that you cannot use export = X syntax; instead, opt for named export syntax. Additionally, avoid attempting to access either class before the module loads—place these actions within a constructor or function executed after the class has been exported.

Answer №2

To properly import classes, use the following syntax:

import { ClassC } from "./ClassC";
instead of
import ClassC = require('ClassC');

For Class B:

import { ClassC } from "./ClassC"; // remember to use this syntax

class ClassB
{
    public static ClassBRef:any;

    constructor()
    {
        console.log(ClassC.TEST);
    }
}
export { ClassB };

For Class C:

import { ClassB } from "./ClassB"; // make sure to use this syntax

class ClassC
{
    public static TEST:number = 1;

    constructor()
    {
        ClassB.ClassBRef;
    }
}

export { ClassC };

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The "variable" used in the React app is not defined, resulting in a no

Following the tutorial of Mosh Hamedani, I attempted to create a react-app. You can watch the tutorial here. I followed his instructions exactly as mentioned. I encountered an issue when trying to pass an argument named product to a function called on on ...

Tips for ensuring nvm is activated whenever the nvmrc file is updated

I have implemented the use of direnv along with an nvmrc file to ensure that nvm install runs every time the directory is entered. This ensures that the correct node version is used when working on the project. However, I have noticed that if another user ...

Ways to incorporate validation into Material-UI form input fields

I have a react functional component that utilizes Material UI form, which includes TextField. The onChange event is managed in the "Container Component". I have added required for client-side form validation, but it doesn't seem to be working. Do I ne ...

Guide to profiling resources in Node.js applications

When developing Node.js applications, it's important to keep track of how your code is performing in terms of memory and IO. By monitoring these metrics, you can identify which parts of your code are causing delays or consuming excessive resources. Th ...

Using JavaScript to adjust the width of the table header

I have a table that I need to adjust the width of using JavaScript or jQuery. <div class="dataTables_scrollHeadInner" > <table class="table table-condensed table-bordered table-striped dataTable no-footer" > <thead ...

Finding and merging duplicate values within a Javascript array

I am working with a dynamically generated array that looks like this: var myArray = ("0% { left:74px; top:202px; }" , "44% { left:427px; top:122px; }", "0% { font-size:11px; }", "55% { font-size:49px; }" ); Within the array, there are 2 entries that ha ...

Trouble arises with the date-picker component in Angular

There's a specific concept known as "campaign duration" where you can select a date between the first and last day of the month. If you choose a date outside this range, such as a date from the following month, the Backend API will respond with an "In ...

The React page fails to load on Ubuntu, yet it works perfectly on the local WSL

It's puzzling. The code that performs flawlessly on my personal computer, smoothly running without any hiccups, fails to operate as expected on an ubuntu server. Upon executing npm start, my local environment exclaims "Compiled successfully!" while t ...

Numerous Controllers in AngularApp failing to function properly

One issue I'm encountering is that only one out of the two controllers within my app seems to be registered: var app = angular.module('MyModule', []); app.controller('FruitCtrl', function($scope) { $scope.fruits = ['appl ...

Enhance your React Typescript High Order Component by incorporating additional properties and implementing them

I am in the process of creating a React HOC with specific requirements: It should take a component as input, modify the hidden property (or add it if necessary), and then return the updated component The rendered component should not display anything whe ...

Issues with Angular 9 application compatibility with IE11

Our Angular 9 project runs smoothly on Google Chrome and Firefox, but nothing appears on IE11. Despite trying various solutions found online and following related blogs, the issue remains unresolved. Here is a snippet from my tsconfig.json: { // Com ...

Is there a method in CSS Grids to wrap the implicit grid while employing grid-auto-flow: column?

How can I achieve a layout consisting of two 4x2 grids that flow into each other, instead of being positioned side by side? Essentially, I want to split an 8x2 grid into two halves and stack them vertically. Is there a way to make the layout wrap around it ...

Vue.js is experiencing issues with updating attributes within nested v-for loops

Exploring the realm of vue.js and react, I am currently in the process of adapting a basic editable HTML table example found in a React book to further my understanding of Vue. Here is a breakdown of what occurs within the code: User clicks on a td elem ...

Error: The function bind is not supported on instance[method] in the AdonisJs framework

I am currently integrating the MQTT-adonis module adonis-mqtt response on Git here in my adonis-js application. However, when trying to serve it, an exception is thrown. TypeError: instance[method].bind is not a function Could anyone provide guidance o ...

Is it possible to loop through each row in a table using Cypress and execute the same actions on every iteration?

I have a frontend built with html/typescript that features a table of variable length containing action buttons in one of the columns. I am looking to create a Cypress test that will click on the first button of the first row, carry out a specific task, an ...

Looping through JavaScript to generate HTML code

I have come across a HTML code snippet that looks like this: <div class="content"> <article class="underline"> <a href="incidente.html"><img id="incidente" src="img/buraco.jpg" alt="Incidente" /></a> ...

Utilizing the power of AWS Lambda in conjunction with moment JS to generate unique

My current time zone is GMT+8, and the AWS region I am using is Singapore (ap-southeast-1). I am facing an issue where there are discrepancies in date calculations between my local machine and when I deploy my code on AWS Lambda. My goal is to ensure that ...

Best practices for implementing JavaScript in JSP pages

After researching various sources, I have come across conflicting opinions on the topic which has left me feeling a bit confused. As someone new to web programming using java EE, I am looking to integrate javascript functions into my code. It appears that ...

The input type file is not correctly inserting an image into the image tag

While I was working on a project, I had a question that got answered but now I need to find a different way to use the solution. I have created a jsFiddle to demonstrate how it currently works. You can view it here: http://jsfiddle.net/TbZzH/4/ However, w ...

Managing conditional filters in MySQL

I am currently utilizing node.js to perform a query based on multiple filters that must all be true. select * from orders ${isFilter ? 'where' : ''} ${orderId !== undefined && orderId ? `order_id = '${orderId}' or ...