Can someone explain the inner workings of the Typescript property decorator?

I was recently exploring Typescript property decorators, and I encountered some unexpected behavior in the following code:

function dec(hasRole: boolean) {
    return function (target: any, propertyName: string) {
        let val = target[propertyName];
        Object.defineProperty(target, propertyName, {
            get() { return val; },
            set(value) { val = hasRole; }
        });
    }
}

class Hey {
    age: number;

    @dec(true)
    hasRole: boolean = false;

    constructor(age: number) {
        this.age = age;
    }
}

let ob = new Hey(22);
console.log(ob);

//Output:

age: 22
hasRole: true
__proto__:
  constructor: class Hey
  hasRole: true
  get hasRole: ƒ get()
  set hasRole: ƒ set(value)
  __proto__: Object

I expected the output to be: 1. OwnProperty -> hasRole = false 2. Prototype property -> hasRole = true. The argument 'target' in the decorator provides the constructor function for static members or prototype of the class for instance members, which may explain the observed functionality.

Would appreciate an explanation on this behavior.

Answer №1

To gain a clear understanding, it is recommended to refer to the transpiled version

function dec(hasRole) {
    return function (target, propertyName) {
        let val = target[propertyName];
        Object.defineProperty(target, propertyName, {
            get() { return val; },
            set(value) { val = hasRole; }
        });
    };
}
class Hey {
    constructor(age) {
        this.hasRole = false;
        this.age = age;
    }
}
__decorate([
    dec(true)
], Hey.prototype, "hasRole", void 0);
let ob = new Hey(22);
console.log(ob);

The code reveals that the class is decorated before creating a new instance

This implies that when the constructor runs, hasRole is already defined in Prototype, so assigning this.hasRole does not change anything: it always assigns to the hasRole parameter in the decorator (which is true)

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

Building a flexible table in React JS based on specific keys: a complete guide

I'm currently working on developing a dynamic table component using React JS. The component at the moment has a fixed header with the most common result keys. Some results contain additional information such as phone numbers and degrees. I'm loo ...

Is there a way to activate a function when clicking on the "View larger map" option within the Google Maps

I am currently in the process of creating a cordova application with ionic and angularjs, where I am using the google maps embed API to include a map within the app. https://developers.google.com/maps/documentation/embed/guide When the user clicks on t ...

showcasing a map on an HTML webpage

Seeking advice on integrating a map feature in HTML to mark store locations. Working on an app for a business community and need help with this specific functionality. Your assistance would be greatly appreciated! ...

Stop files from being downloaded every time the page is visited

Within my Vue.js application, there is an animation that appears on a specific page. However, each time I visit that page, the assets for the animation are re-downloaded from scratch. Although the app does get destroyed when leaving the page, using v-show ...

Dealing with Typescript in Node.js: Handling the error 'Property not found on type Global & typeof globalThis'

I recently encountered an issue with my NodeJS app that is built with typescript and global.d.ts file. The strange part is that everything works fine in my old application, but when I try to run the new one using ts-node-dev ts-main-file.ts, I encounter an ...

Which is better for creating a gradual moving background: Javascript or CSS?

I'm attempting to discover how to create a background image that scrolls at a slower pace than the page contents. I'm currently unsure of how to achieve this effect. A great example of what I'm aiming for can be seen here Would this require ...

Methods to prompt a user to select an option using Bootstrap

I have been struggling with this problem for hours and it's really starting to frustrate me! Currently, I am incorporating Twitter Bootstrap along with bootstrap-min.js. This is the code snippet in question: <select id="assettype" name="assettyp ...

Issue encountered when attempting to utilize Next-Auth alongside Credentials Provider to authenticate within a pre-existing system

I am currently utilizing the Next-Auth Credentials provider for authentication purposes through our existing API. Following the guidelines provided at https://next-auth.js.org/configuration/callbacks the code snippet used is as follows: callbacks: { ...

Searching in TypeScript tables with Angular's search bar

I've successfully completed a basic CRUD application, but now I need to incorporate a Search Bar that can filter my table and display rows with matching letters. I'm unsure how to approach this in my component. I've seen examples using pipe ...

Styling Discord with NodeJS

After coding with Python for Discord, I decided to switch to JavaScript for its wider functionality. However, I encountered a formatting issue with a specific line of code while testing out a music bot in JS. The bot was sending an embed message, but I wan ...

Utilizing Express.js: Passing the req Object to Middleware without the Need for a New Multer Route

Hello to the Express.js and StackOverflow communities! I hope this question is not a duplicate, as I searched and found nothing similar. Currently, I am working on a project using Multer with Express to enable users to upload images, which will be saved a ...

Transmitting information from JavaScript to a PHP script

I am currently using a function that grabs text from a PHP file on our server and inserts it into an HTML page. However, I now need to modify this function in order to SEND data (specifically a couple of JavaScript variables) to the PHP file instead of si ...

Trouble with hide/show loop in setTimeout function

I have a special animation with 3 text items that are initially invisible. The goal is to make these items appear one by one with a delay of 2 seconds after clicking a button. Each item should be visible for 1 second before fading out and making way for th ...

Error: We were unable to recognize the syntax in /service-details/1139#overview for Angular 5

I have been working on implementing simple routing in Angular. Everything seems to be functioning correctly, however, I encountered an error when attempting client-side routing using nav tabs to navigate within the same page. Here is a snippet of my code: ...

Showing Firebase messages in a NativeScript ListView in an asynchronous manner

I am currently struggling to display asynchronous messages in a ListView using data fetched from Firebase through the popular NativeScript Plugin. While I have successfully initialized, logged in, and received the messages, I'm facing challenges in ge ...

Encountering an issue while trying to install font-awesome in an Angular project

Encountering an error while trying to install font-awesome in angular npm install --save @fortawesome/fontawesome-free npm ERR! code UNKNOWN npm ERR! syscall rename npm ERR! path C:\Users\pratish.devangan\OneDrive - HCL Technologies Ltd&bso ...

Rendering a Subarray using Map in ReactJS

I have an object containing data structured like this: [{"groupid":"15","items":[ {"id":"42","something":"blah blah blah"}, {"id":"38","something":"blah blah blah"}]}, {"groupid":"7","items": [{"id":"86","something":"blah blah blah"}, {"id":"49","somethin ...

Unable to supersede CSS module styling using global or external stylesheets in React, Next.js, or React Native

I'm facing a challenge finding a solution to a basic issue. I have a component that is initially styled using a class from a *.module.css file. However, I want to replace this style with one from a global stylesheet or another stylesheet but I can&apo ...

To enhance user experience, consider incorporating a 'Next Page' feature after the completion of every four paragraphs,

Here is a code snippet that can be used to print 'n' number of paragraphs: <% while(rs.next()){ String para=rs.getString("poems"); %> <p> <%=para%> </p> <!-- n number of p tags are printe ...

Upgrade your function to utilize Firebase V9 with Next.js framework

I recently updated my project to use version 9 of firebase, and since then, I've been encountering some code errors that I'm struggling to resolve. The previous function had the following structure, but now I need to update it to work with the n ...