Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can I use decorators on object properties?

Normally I apply the decorator like this:

class SpecialMethods {
    @Deco
    static someMethod() {
    }
}

Is there also some way to use it with a plain object rather than a class:

const SpecialMethods = {
    @Deco
    someMethod: () => {}
}
like image 377
Chris Avatar asked Dec 17 '17 21:12

Chris


1 Answers

Yes, but its not very practical. You can invoke the decorator for the properties of an object, but not in the same way as you would decorate a class and its content.

Given the following decorator:

const TestDecorator = (at: string) => {
    return function (target: any, prop: string, descriptor?: PropertyDescriptor) {
        console.log(`decorated at ${at}}`);
    }
}

Would be used as followed in a class:

class TestClass {
    @TestDecorator('class method')
    public testMethod() { }
}

However, it can't be applied the same way as above for a property:

const testObj = {
    @TestDecorator('property method')
    testMethod: () => { }
};

To work around this, you can invoke the decorator at the property.

At first you have to declare your object with all its properties:

const testObj = {
    testMethod: () => { }
};

My decorator expects a curried value:

const deco = TestDecorator('property method');

Now you have to manually invoke the deco decorator for the property in testObj:

deco(testObj, 'testMethod');

If you need the propertyDescriptor in your decorator (it is not in the OP), you'll have to manually provide it as well:

deco(testObj, 'testMethod', Object.getOwnPropertyDescriptor(testObj, 'testMethod'));

Here is a TS playground. Check the output in the console.

like image 59
Shane Avatar answered Sep 29 '22 09:09

Shane