typescript add some flair to the setter function

I'm attempting to enhance a setter function within a class in the following manner:

export class SearchResultSortBy{
    private sortByChoice;
    constructor() { ...} 

     /* getters & setters */
    get sortBy() {
        return this.sortByChoice;
    };

    @myDeco({o:'something',o2:'another something'})
    set sortBy(sortBy) {
        this.sortByChoice = sortBy;
    };

 }

utilizing the given decorator:

export function myDeco(element:any){
        return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
            descriptor.set = function(...args: any[]) {
                console.log("The method args are: " + JSON.stringify(args)); // pre
                var result = originalMethod.apply(this, args);               // execute and store the result
                someOtherStaticClass.someFunc(element);               // post
                return result;                                               // return the result of the original method
            };
        return descriptor;
   };
}

however, the decorator is not being invoked/does not have any effect.
when I place the @myDeco above a getter function instead, the decorator is triggered and functions as intended, which is quite unusual... (decorates the setter func.)

is it feasible to decorate a setter function in typescript?

Answer №1

By reversing the order of getter and setter, you can trigger the decorator to be invoked.

@myDeco({o:'something',o2:'another something'})
set sortBy(sortBy) {
    this.sortByChoice = sortBy;
};

get sortBy() {
    return this.sortByChoice;
};

Since you can only decorate either the setter or the getter (but not both), the sequence in which they are declared is crucial.

EDIT

The reason behind the limitations on decorating both the setter and getter methods is due to how properties are defined in JavaScript. In your case, the "sortby" property consists of a single property with both setter and getter functions defined. Decorators are applied to properties, meaning that they can only be attached once to a property regardless of whether it's the setter or getter that is decorated. The resulting JS code will remain identical. To better understand this concept, take a look at the simplified generated JS code based on your example:

function myDeco(element) {
    return function (target, propertyKey, descriptor) {
        descriptor.set = function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i - 0] = arguments[_i];
            }
            return 12; 
        };
        return descriptor;
    };
}
var SearchResultSortBy = (function () {
    function SearchResultSortBy() {
    }
    Object.defineProperty(SearchResultSortBy.prototype, "sortBy", {
        get: function () {
            return this.sortByChoice;
        },
        set: function (sortBy) {
            this.sortByChoice = sortBy;
        },
        enumerable: true,
        configurable: true
    });
    ;
    ;
    __decorate([
        myDeco({ o: 'something', o2: 'another something' }), 
        __metadata('design:type', Object), 
        __metadata('design:paramtypes', [Object])
    ], SearchResultSortBy.prototype, "sortBy", null);
    return SearchResultSortBy;
})();

Notice how the __decorate function operates and its input requirements.

The behavior where the TypeScript compiler prioritizes the first declaration (getter without decorator) over any decorators applied to the sibling setter could potentially be a bug in the compiler that may be addressed in future releases. It would be beneficial if someone more knowledgeable could provide insights or contradict this observation.

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

Why is the AngularJS 2 child @Component not being replaced in this scenario?

UPDATE: It seems that the issue lies in how I am structuring and serving the project rather than a coding problem. If I find a solution, I'll be sure to update this post. Thank you for your assistance. I'm currently developing an AngularJS 2 ap ...

The 'resp' parameter is assumed to have an unspecified type, shown as 'any'. This is an error in Angular

} ErrorHandler(response){ console.debug(response.json()); } DataHandler(response){ this.ClientModels = response.json(); } I have developed two functions to handle error and success responses, but an error message is showing up saying "para ...

Is it possible to run NestJS commands without relying on npx?

I recently installed nestjs using npm, but I encountered an issue where it would not work unless I added npx before every nest command. For example: npx nest -v Without using npx, the commands would not execute properly. In addition, I also faced errors ...

Angular's FormGroup for reactive forms is a powerful feature that allows for

Why am I unable to type in the input field before setting a value? html <form action="" [formGroup]="titleForm"> <input class="note-title" type="text" formControlName="title"> </form> ...

Cannot locate: Unable to find the module '@react-stately/collections' in the Next.js application

While working on my Next.js app, I decided to add the react-use package. However, this led to a sudden influx of errors in my Next.js project! https://i.stack.imgur.com/yiW2m.png After researching similar issues on Stackoverflow, some suggestions include ...

Consolidating Angular 4 Observable HTTP requests into a single Observable to optimize caching

I am currently working on an Angular 4 application that serves as a dashboard for a system. Several different components within the application make calls to the same REST endpoint using identical TypeScript service classes. While this setup functions corr ...

Error: Unable to generate MD5 hash for the file located at 'C:....gradle-bintray-plugin-1.7.3.jar' in Ionic framework

When attempting to use the command ionic cordova run android, an error occurred that prevented the successful execution: The process failed due to inability to create an MD5 hash for a specific file in the specified directory. This issue arose despite suc ...

Verification of unique custom string

How can I ensure that a string follows the specific format of x.xx.xxxxx? The first character is mandatory, followed by a period, then two characters, another period, and finally any number of characters of varying lengths. ...

Transforming a material-ui component from a class to a function

Currently, I am in the process of learning material-ui, and it seems that most of the code examples I come across are based on classes. However, the new trend is moving towards using functions instead of classes due to the introduction of hooks. I have be ...

Set an enumerated data type as the key's value in an object structure

Here is an example of my custom Enum: export enum MyCustomEnum { Item1 = 'Item 1', Item2 = 'Item 2', Item3 = 'Item 3', Item4 = 'Item 4', Item5 = 'Item 5', } I am trying to define a type for the f ...

Issue: the module '@raruto/leaflet-elevation' does not include the expected export 'control' as imported under the alias 'L' . This results in an error message indicating the absence of exports within the module

Looking for guidance on adding a custom Leaflet package to my Angular application called "leaflet-elevation". The package can be found at: https://github.com/Raruto/leaflet-elevation I have attempted to integrate it by running the command: npm i @raruto/ ...

The continuous re-rendering is being triggered by the Async/Await Function

I am facing an issue with fetching data from the backend using axios. The function is returning a Promise and each time I call it, my component keeps rendering continuously. Below is the code snippet: import { useState } from "react"; import Ax ...

Experiencing difficulty in transferring array information from a parent component to a child component within an

I'm currently working on a task where I need to pass data from a parent component to a child component. The data consists of an array that is nested within another array. parent.component.html <div *ngFor="let parent of parentArray; index as ...

Tips for conducting a worldwide search in Angular 2?

I'm currently navigating my way through angular2 development and I am aiming to conduct a comprehensive search within an array of JSON objects. To illustrate, consider this sample array: invoiceList = [ { invoiceNumber: 1234, invo ...

Maintaining the consistent structure of build directories within a Docker container is crucial, especially when compiling TypeScript code that excludes the test

Our application is built using TypeScript and the source code resides in the /src directory. We have tests located in the /tests directory. When we compile the code locally using TSC, the compiled files are deposited into /dist/src and /dist/test respectiv ...

Differentiating between model types and parameters in Prisma can greatly enhance your understanding of

Consider the following scenario: const modifyData = async(data, settings) => { await data.update(settings) } In this case, the data refers to any data source, and the settings consist of objects like where and options for updating the data. How can ...

How to resolve the issue of not being able to access functions from inside the timer target function in TypeScript's

I've been attempting to invoke a function from within a timed function called by setInterval(). Here's the snippet of my code: export class SmileyDirective { FillGraphValues() { console.log("The FillGraphValues function works as expect ...

Ionic Framework: Implementing a search bar in the navigation bar

I am looking to include a search icon in the navbar of my Ionic project <ion-navbar> <ion-buttons left> <button ion-button menuToggle> <ion-icon name="menu"></icon-icon> </button> </ion-bu ...

Is it necessary to also include template-only attributes in my controller's definition?

I'm working on a directive template that features a basic toggle variable. <div ng-mouseenter="$ctrl.myToggle = true" ng-mouseleave="$ctrl.myToggle = false"> ... </div> <div ng-if="$ctrl.myToggle"> ... toggled content </div> ...

Is it possible to assign a property value to an object based on the type of another property?

In this illustrative example: enum Methods { X = 'X', Y = 'Y' } type MethodProperties = { [Methods.X]: { x: string } [Methods.Y]: { y: string } } type Approach = { [method in keyof Method ...