Exploring the World of TypeScript Decorators

I'm having trouble getting my custom @enumerable decorator to work properly. I followed the example in the documentation, but it's not functioning as expected. Am I overlooking something?

Decorator

export function enumerable(value: boolean) {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        descriptor.enumerable = value;
    };
}

Class

export class MyClass {

    @enumerable(true)
    get getter():string {
        return 'value';
    }

}

Test

var cls = new MyClass();
console.log(cls.propertyIsEnumerable('getter')); // returns false, expected true
console.log(Object.keys(cls));                   // returns [], expected ["getter"]
console.log(JSON.stringify(cls));                // returns {}, expected {"getter":"value"}

tsconfig.json

{
    "compilerOptions": {
        // "target": "ES2015",
        "target": "ES5",
        "module": "commonjs",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "noImplicitAny": false
    }
}

Answer №1

The decorator allows the getter to be enumerable in the prototype rather than the instance.

Experiment with this code snippet:

console.log(MyClass.prototype.propertyIsEnumerable('getter')); // true
console.log(Object.keys(MyClass.prototype)); // ["getter"]
console.log(JSON.stringify(MyClass.prototype));  // {"getter":"value"}

However, if you iterate through the instance using a for/in loop, you will see:

for (let item in cls) {
    console.log(item);
}

This will output: getter.
The reason behind this behavior is explained by Object.keys:

it generates an array of an object's own enumerable properties, following the same order as a for...in loop (the key difference being that a for-in loop also includes properties from the prototype chain)


Edit

To control how instances are stringified, consider implementing a toJson() method like this:

class MyClass {
    private x: number = 4;
    private str: string = "str";

    get getter(): string {
        return 'value';
    }

    toJson(): string {
        return JSON.stringify(Object.assign({}, this, { "getter": this.getter }));
    }
}

var cls = new MyClass();
console.log(cls.toJson()); // "{"x":4,"str":"str","getter":"value"}"

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

Using Angular template to embed Animate CC Canvas Export

Looking to incorporate a small animation created in animate cc into an angular template on a canvas as shown below: <div id="animation_container" style="background-color:rgba(255, 255, 255, 1.00); width:1014px; height:650px"> <canvas id="canv ...

Validating dates in TypeScript

Currently, I am studying date handling and have an object that contains both a start and end date. For example: Startdate = "2019-12-05" and Enddate = "2020-05-20" My goal is to establish a condition that first verifies the dates are not empty. After tha ...

Checking an Angular 2 Component with Constructor Argument

Imagine having an Angular 2 Component containing two input parameters: @Component{... (omitted for clarity)} export class SomeComponent { @Input() a: number @Input() b: number } When needing to test this component, the process typically involves someth ...

Why am I having trouble iterating through my array object?

Trying to showcase the contents of object within an array. However, unable to showcase any results. Why is this happening? This is what I've attempted so far: Demo available here: https://stackblitz.com/edit/ionic-dsdjvp?file=pages%2Fhome%2Fhome.ts ...

When logging `self`, the output field is present; however, attempting to log `self.output` results in

I've encountered a strange issue. When I use console.log(self) to log the variable, it shows that the output key is set and contains all the values. However, if I try to log console.log(self.output), it returns undefined. Does anyone know why this is ...

Autocomplete feature shows usernames while storing corresponding user IDs

I am looking to enhance the autocomplete functionality in my application while also ensuring that the selected user ID is stored in the database. Specifically, I want the autocomplete feature to display user names for selection purposes, but instead of re ...

Tips for altering Koa's HTTP status code for undeclared paths

If an undefined route is accessed on a Koa server, what is the best method to change the default HTTP status code and response body? Currently, Koa returns a 404 status and 'Not Found' text in the body. I intend to modify this to 501 (Not implem ...

Obtaining Data from a Database Using Angular

I have developed a front-end website using Angular as my framework, integrated with node.js. To interact with the database, I created a "server.ts" file and connected it successfully to my DB. Now, my goal is to fetch data from the database and display i ...

"Encountering issues when trying to retrieve a global variable in TypeScript

Currently facing an issue with my code. I declared the markers variable inside a class to make it global and accessible throughout the class. However, I am able to access markers inside initMap but encountering difficulties accessing it within the function ...

"Unexpected compatibility issues arise when using TypeScript with React, causing errors in props functionality

Just the other day, my TypeScript+React project was running smoothly. But now, without making any changes to the configurations, everything seems to be broken. Even rolling back to previous versions using Git or reinstalling packages with NPM does not solv ...

Looking for a solution to the error message: "X is not able to be assigned to the type 'IntrinsicAttributes & Props'"

Greetings everyone! I need some assistance in setting up single sign-on authentication using React, Azure AD, and TypeScript. I'm encountering a type error in my render file and I'm unsure of how to resolve it. Below is the specific error message ...

Monitor the change in values upon pressing the submit button on Angular

I am currently working with an edit form that contains data in the input fields. <ng-form #infoForm="ngForm" novalidate> <div> <label for="firstName">First Name :</label> <input type=" ...

In the CallableFunction.call method, the keyword "extends keyof" is transformed into "never"

In the following method, the type of the second parameter (loadingName) is determined by the key of the first parameter. (alias) function withLoading<T, P extends keyof T>(this: T, loadingName: P, before: () => Promise<any>): Promise<void ...

Angular 16 HttpClient post request with asynchronous action

Here I am working on integrating JWT in Angular with a .Net Core API. When I start my Angular server and launch the application, I encounter the following scenarios: Attempting with correct credentials initially fails, but retrying allows it to work. Tryi ...

When using TypeScript, my sorting function returns a value of 0 for all time values

I have been trying to sort this JSON data by date using the provided code, but it does not seem to work as expected. Below is a snippet of my JSON: { "StatusCode":0, "StatusMessage":"OK", "StatusDescription":[ { "id":"1", ...

Utilizing React with Typescript to create JSX text translation files

My task involves translating text stored in a file... ///translations.txt const TEXT: { [x: string]: { [y: string]: string } } = { en: { joinNow: <React.Fragment>Join <b>Now<b/></React.Fragment>, signUp: <React.Fragmen ...

Updating the state in React is causing significant delays

In my React project, I am utilizing the pdf-lib (JS library) for some intensive tasks using async/await. My goal is to update a progress bar by modifying the state. However, when I use setState within a setTimeout, the state changes are not reflected unt ...

ng2-toastr in conjunction with akveo/ng2-admin - Styles not being applied

I recently integrated ng2-toastr into my akveo/ng2-admin dashboard, utilizing the latest version with Angular 4. Following the provided installation documentation, I imported the necessary CSS in the index.html file and declared ToastModule in the app.modu ...

What is the method for exporting all functions from a TypeScript file with a default export included?

An example of the export type mentioned is React. To use it, we can include the following code: import React, {Component} from "react". This allows us to access both React.Component and Component. What steps are necessary to make this possible? ...

If placed in the same document, will promises be executed sequentially?

Let's say I have a function in one file that returns a promise: public async a():Promise<string>{ return 'hi' } In another file, I use this function like so: await service.a.then( hi =>console.log(hi)).catch(err=>{throw err}); ...