Home > Back-end >  Decorator to add a method which returns class name and the string passed in brackets
Decorator to add a method which returns class name and the string passed in brackets

Time:01-14

The task is to implement the class decorator to add the “identify“ class method which returns a class name with the information passed in the decorator.
Example:

@identifier('example')
    class Test {}
    
    const test = new Test();
    console.log(test['identify']()); // Test-example  

Unit tests:

describe('identifier', () => {
    it('should return Test-example from identify', () => {
        @identifier('example')
        class Test {}
        const test = new Test();
        assert.strictEqual(test['identify'](), 'Test-example');
    });

    it('should return ClassA-prototype from identify', () => {
        @identifier('prototype')
        class ClassA {}
        const test = new ClassA();
        assert.strictEqual(test['identify'](), 'ClassA-prototype');
    })  

I tried to do something with this decorator,but what i have now is only console logging the string passed in brackets,i have no idea how to print the class name where decorator is used.. Please help. :
My function :

function identifier(passedInformation:string):string {
  console.log('-' passedInformation)
}  

Edit : I almost did the function :

function identifier(...args: any): ClassDecorator {
    return function <TFunction extends Function>(
        target: TFunction
    ): TFunction | void {
        return target.name '-' args)
    }
}  

if i change the return target.name '-' args with console log,it gives the result expected in unit test logged in console,but the problem is that i get : type 'string' is not assignable to type 'void | TFunction' And this in junit.xml :

<failure message="" type="TypeError"><![CDATA[TypeError: 
    at DecorateConstructor (node_modules\reflect-metadata\Reflect.js:544:31)
    at Object.decorate (node_modules\reflect-metadata\Reflect.js:130:24)
    at __decorate (test\index.ts:4:92)  

But if i change the return to console log,i get this in junit.xml:

<failure message="test.identify is not a function" type="TypeError"><![CDATA[TypeError: test.identify is not a function
    at Context.<anonymous> (test\index.ts:99:44)

What is wrong? How can i return my result and finish this task?

Edit 2 :
Using @Vallarasu SambathKumar solution below,i dont get any errors in the code editor,but in junit.xml i get next errors and it can not pass the unit test.. :

 <failure message="" type="TypeError"><![CDATA[TypeError: 
    at DecorateConstructor (node_modules\reflect-metadata\Reflect.js:544:31)
    at Object.decorate (node_modules\reflect-metadata\Reflect.js:130:24)
    at __decorate (test\index.ts:4:92)
    at C:\Users\artio\Desktop\6 Decorators\decorators\test\index.ts:81:20
    at Context.<anonymous> (test\index.ts:85:10)
    at processImmediate (internal/timers.js:439:21)]]></failure>

How to fix this,whats the problem?

CodePudding user response:

You may as well pass instance as a parameter and access it's type

function identifier(passedInformation:string) {
    return function (target) {
        console.log(target.constructor.name   '-' passedInformation);
    }
}

and use it like

test['identify'](test)

improvised from - Get an object's class name at runtime

CodePudding user response:

With @Vallarasu SambathKumar solution and a little more documentation,i came up with this function :

function identifier(...args: any): ClassDecorator {
    return function <TFunction extends Function>(
        target: TFunction
    ): TFunction | any {
        var identify = target.prototype.identify;
        Object.defineProperty(target.prototype, 'identify', {
            value: function() {
                return target.name   "-"   args;
            }
        });
        return identify;
    };
}

I did the identify method like the task needed and then returned it,no errors at unit tests and at run time,perfect.

  •  Tags:  
  • Related