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

Here is an example showcasing how to use Angular 2 to make an

How can I correctly retrieve json data from an http get request in Angular 2? Currently, I am working on testing some local data with a mocked endpoint. Although I am able to see the result in the http.get() method, I am facing issues when trying to assign ...

Having issues with an Angular reactive form that includes a custom form-level validator and the 'blur' updateOn option?

Having issues combining the following: angular reactive form custom validator at form level (cross-field validator) usage of the 'updateOn' option set to 'blur' A demonstration of the problem can be found in this simple stackblitz: h ...

What is the best way to determine in component.html whether the column type is equal to 1 to show the label text "Active,"

Having trouble checking the value of an object named ReportControl. If the column type is 1, display the label "active"; otherwise, display the label "not active" on reportcomponent.html. The data for the ReportControl object is as follows: {"reportId": ...

Tips for waiting for an observable loop

When using my application, the process involves uploading a series of images in order to retrieve the file IDs from the system. Once these IDs are obtained, the object can then be uploaded. async uploadFiles(token: string):Promise<number[]> { let ...

Determining the data type of a generic variable within an Angular component

I'm currently in the process of developing a versatile component that can handle data of only two specific types: interface X{ name: string, path: string, type: string, } interface Y{ name: string, path: string, } Both types X a ...

"Efficient ways to calculate the total sum of an array of objects based on a specific property

I currently have a straightforward method that calculates the total sum of an object array based on one of the properties. const calculateSum = <T extends object, K extends keyof T>(array: T[], property : K) : number =>{ let total = 0; if ( ...

Retrieve the file from the REST API without using the window.open method

I'm looking for a method to download files from an API without using window.open(). I want the download process to start immediately upon calling the API. Currently, I am downloading an .xls file generated by a REST API using window.open() API Endpo ...

Integrating Typescript into function parameters

I am attempting to make my function flexible by allowing it to accept either a string or a custom type onPress: (value: string | CustomType)=>void But when I try to assign a string or CustomType, the compiler gives an error saying is not assignable to ...

What is the method for enabling imports from .ts files without file extensions?

While trying to open a Svelte project with TypeScript, I encountered an issue where all imports from .ts files were showing "Cannot resolve symbol" errors. https://i.stack.imgur.com/FCVxX.png The errors disappear when the .ts extension is added to the im ...

The program was expecting an array to start, but instead encountered an object. Any suggestions on how to convert

{ "workingHours": [ { "date":"2023-02-01", "amount":3, "freigegeben":false } ] } Whenever I include this in my re ...

Inquiry regarding the return value of 'async-lock' in nodejs

I am utilizing the async-lock module in my typescript project to handle concurrency. However, I am encountering difficulties with returning the result within lock.acquire(...) {...}. Any guidance on how to resolve this issue would be greatly appreciated. ...

Omit an enum item from selection when referencing the key within the Enum

Within my enum, I have defined multiple keys: export enum MyTypeEnum { one = 'one', two = 'two', three = 'three', four = 'four' } To ensure certain types must contain these keys, I use the following ...

What are the ways to recognize various styles of handlebar designs?

Within my project, I have multiple html files serving as templates for various email messages such as email verification and password reset. I am looking to precompile these templates so that they can be easily utilized in the appropriate situations. For ...

Automatically select the unique item from the list with Angular Material AutoComplete

Our list of document numbers is completely unique, with no duplicates included. I am attempting to implement a feature in Angular Material that automatically selects the unique entry when it is copied and pasted. https://i.stack.imgur.com/70thi.png Curr ...

"Troubleshooting the issue of Angular's select binding causing a disruption

The Angular version being used is 1.4.7. Within the model in question, there are two objects: 'systems', which is an array, and 'selectedSystem'. The desired outcome is for 'selectedSystem' to reference one of the objects wit ...

What is the procedure for inputting the settings for the export module in webpack?

I am currently working on setting up this webpack configuration file. However, I encountered an issue where the error message states that "any" is being used as a value instead of a type. How can I resolve this issue? module.exports:any = { ...

Various gulp origins and destinations

I am attempting to create the following directory structure -- src |__ app |__ x.ts |__ test |__ y.ts -- build |__ app |__ js |__ test |__ js My goal is to have my generated js files inside buil ...

How do I add a new item to an object using Ionic 2?

example item: this.advData = { 'title': this.addAdvS2.value.title , 'breadcrumb': this.suggestData.breadcrumb, 'price': this.addAdvS2.value.price ...

Is there a way to restrict props.children.some to only accept image types?

Currently troubleshooting the following issue: An error is occurring: 'Property 'type' does not exist on type 'true | ReactChild | ReactFragment | ReactPortal'. Property 'type' does not exist on type 'string'. ...

The component 'Form' cannot be utilized in JSX because its return type, 'ReactNode', is not a valid JSX element

I'm facing an issue with my Next.js application written in TypeScript after updating react-bootstrap. After the update, I am encountering the following error when attempting to use the Form component from react-bootstrap: react-bootstrap: ^2.10.3 @typ ...