The enigmatic occurrence of TypeScript decorators: when a decorator parameter mysteriously transforms into undefined in a particular scenario

I have been working on developing my own Object-Relational Mapping (ORM) system and I encountered an interesting issue in TypeScript that I am trying to understand. If anyone can provide some insight or clarification on this matter, it would be greatly appreciated.

Let me share a simplified version of the basic structure where this peculiar behavior occurs.

There is a property decorator that accepts a parameter of a class type.

// This is optional but helps in explicitly defining the entityClass type
export abstract class Entity { }


export function Decorator(entityClass: typeof Entity) {
    return function(target: any, propertyName: string) {
        console.log(entityClass);
    }
}

File containing Class A: EntityA.ts

import { Entity, Decorator } from "./index";
import { EntityB } from "./EntityB";

export class EntityA extends Entity {

    @Decorator(EntityB)
    public propertyA: any;
}

File containing Class B: EntityB.ts

import { Entity, Decorator } from "./index";
import { EntityA } from "./EntityA";

export class EntityB extends Entity {

    @Decorator(EntityA)
    public propertyB: any;
}

A snippet of code to invoke TypeScript to utilize the decorator for logging purposes:

run.ts

import { EntityA } from "./EntityA";
import { EntityB } from "./EntityB";


const objA = new EntityA();
const objB = new EntityB();

When running this script, the output is as follows:

undefined
[Function: EntityB]

The occurrence of undefined is what I find intriguing. If I remove @Decorator(EntityB) line from EntityA.ts and run the script again, the undefined disappears yielding the expected result:

[Function: EntityA]

Am I misunderstanding something about decorators, or could this be a potential bug in TypeScript?

Answer №1

The code contains circular references - specifically, the relationship between EntityA and EntityB is interdependent.

When initializing EntityA, the value passed into @Decorator(EntityB) for EntityB is 'undefined', causing the decorator to capture this value.

On the other hand, when initializing EntityB, EntityA is already in existence, resulting in everything working as expected.

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

Currently, I am collaborating on an e-commerce endeavor utilizing TypeScript and sanity.io, encountering an issue along the way

Encountering an Uncaught TypeError message: Cannot read properties of undefined (reading '_ref'). While attempting to utilize code for displaying API content on a webpage, what might be causing this issue and how can it be resolved to successful ...

The functionality of "subscribe()" is outdated if utilized with "of(false)"

My editor is flagging the usage of of as deprecated. How can I resolve this issue and get it working with of? public save(): Observable<ISaveResult> | Observable<boolean> { if (this.item) { return this.databaseService.save(this.user ...

Combining Angular with X3D to create a seamless integration, showcasing a minimalist representation of a box

I am brand new to web development, and I am feeling completely overwhelmed. Recently, I decided to follow the Angular tutorial by downloading the Angular Quickstart from this link: https://github.com/angular/quickstart. My goal was to add a simple x3d ele ...

Sending nested JSON in Angular 2 Post Request

Are there any efficient ways to handle the task of importing raw JSON data and posting it to a server using an import function? For example, if a user copies and pastes the following JSON: { "name": "testing", "design": [ { "name": "test", ...

Guide on implementing Regular Expressions in Directives for validation in Angular 8

Managing 8 different angular applications poses its unique challenges. In one of the applications, there is a directive specifically designed for validating YouTube and Vimeo URLs using regular expressions. Unfortunately, once the RegExp is declared, ther ...

Seeking out a particular key within a JSON object and then finding a match based on the id within that key's array - how can it be

Recently, I've been exploring JavaScript and encountering challenges when trying to apply array methods on objects. For instance, I received a fetch response and my goal is to extract the 'entries' key and then utilize the native Array.find( ...

Utilize the RRule library in JavaScript by incorporating the rrule.min.js script

I am having trouble integrating the library https://github.com/jakubroztocil/rrule into my website. Whenever I try to do so, I encounter the error: Uncaught SyntaxError: Unexpected token { I have attempted the following: <!DOCTYPE html> <html ...

Tips for modifying only one property after receiving an object from an HTTP GET request

Within my Angular application, I have defined an object structure like this: export class Article { id: number; author: number; title: string; content: string; date: Moment; readingTime: number; draft: boolean; constructor(obj: Partial< ...

`How can we efficiently transfer style props to child components?`

Is there a way to pass Props in the Style so that each component has a unique background image? Take a look at this component: countries.astro --- import type { Props } from 'astro'; const { country, description } = Astro.props as Props; --- & ...

Angular2 ngIf directive issue after initial button click

I have recently started using the Angular2 Framework, so please bear with me if I make any common mistakes. I have set up two forms in separate div tags: one for logging in and another for password reset. Below the login form, there is a link that, when cl ...

Problem encountered in a simple Jest unit test - Unexpected identifier: _Object$defineProperty from babel-runtime

Struggling with a basic initial test in enzyme and Jest during unit testing. The "renders without crashing" test is failing, as depicted here: https://i.stack.imgur.com/5LvSG.png Tried various solutions like: "exclude": "/node_modules/" in tsconfig "t ...

Angular displays the error message TS2339, stating that the property 'handleError' is not found on the 'HeroService' type

Hey everyone, I know there are already a few questions out there about Typescript compilation errors, but I'm facing a unique challenge that I can't quite figure out. I'm currently working on the Angular Tour of Heroes app and trying to com ...

Is it possible to enable typescript to build in watch mode with eslint integrated?

Can this be achieved without relying on webpack or other bundlers? Alternatively, is the only solution to have two separate consoles - one for building and another for linting? ...

Differentiating Between Observables and Callbacks

Although I have experience in Javascript, my knowledge of Angular 2 and Observables is limited. While researching Observables, I noticed similarities to callbacks but couldn't find any direct comparisons between the two. Google provided insights into ...

Setting a Validator for a custom form control in Angular: A step-by-step guide

I need to apply validators to a specific control in formGroup from outside of a custom control component: <form [formGroup]="fg"> <custom-control formControlName="custom"> </custom-control> </form> this. ...

Manipulating Data in TypeScript: Creating a Mutated Copy of a List of Dictionaries

After going through multiple answers, it appears that there might be a logical error. However, I am struggling to find a solution for this issue. In TypeScript/JavaScript, I have two lists of dictionaries. One list is a copy of the other for tracking purp ...

The array is not empty but the length is being displayed as zero

I am facing an issue in my project where I can successfully print the array in console, but I am unable to retrieve the length and access the first element. Here is the code snippet: checkout.component.ts: ngOnInit() { this.booksInCheckout = this.ch ...

The Nestjs ClientMqtt now has the capability to publish both pattern and data to the broker, as opposed to just sending

I am currently utilizing Nestjs for sending data to a Mqtt Broker. However, I am facing an issue where it sends both the pattern and data instead of just the data in this format: { "pattern": "test/test", "data": " ...

Having trouble establishing a connection with mongoose and typescript

When attempting to establish a connection using mongoose, I consistently encounter the errors outlined below. However, if I use MongoClient instead, everything functions as expected. import connectMongo from '../../lib/connectMongo' console.log( ...

Observable<void> fails to trigger the subscriber

I am currently facing a challenge with implementing a unit test for an Observable in order to signal the completion of a process. While there is no asynchronous code in the logout function yet, I plan to include it once the full logic is implemented. The m ...