Mahmoud Sharif
Mahmoud Sharif

Reputation: 48

Typescript how to change the function result without modifying the function

how to let multiply & subtract executed once addOne function executed and affect its result ((2+1)*2)-1 =5

class MathClass{

   @subtract(1)
   @multiply(2)
   addOne(number:number) {
       return number+1;
   }
}

console.log(new MathClass().addOne(2)) //should print 5

Upvotes: 0

Views: 208

Answers (1)

hoangdv
hoangdv

Reputation: 16127

Create 2 decorator for 2 operator as you want. With you case, you can create a decorator factory to reuse the code:

function operatorFactory(operator: (result: number) => number) {
  return (
    target: Object,
    propertyName: string,
    propertyDescriptor: PropertyDescriptor,
  ) => {
    const method = propertyDescriptor.value;

    propertyDescriptor.value = function (...args: any[]) {

      const result = method.apply(this, args); // Call original function

      return operator(result); // Call operator
    }

    return propertyDescriptor;
  } 
}

function subtract(subtrahend: number = 1) {
  return operatorFactory((num: number) => {
    return num - subtrahend;
  });
};

function multiply(factors: number = 1) {
  return operatorFactory((num: number) => {
    return num * factors;
  });
};

As you see operatorFactory get a parameter is a function, the function define the way you do with the result - the result of before operator.

subtract decorator get a parameter is a number - subtrahend, and it calls operatorFactory with "subtract" operator.

The same for multiply.

Note, the order of method decorator is very important. With your case ((number+1)*2)-1 , the order will be as you think:

class MathClass {
  @subtract(1)
  @multiply(2)
  addOne(number: number) {
    return number + 1;
  }
}

console.log(new MathClass().addOne(2)) // Print 5

If you reverse the order, you will have a operator like ((number+1)-1)*2, with code as:

class MathClass {
  @multiply(2)
  @subtract(1)
  addOne(number: number) {
    return number + 1;
  }
}

console.log(new MathClass().addOne(2)) // Print 4

Upvotes: 1

Related Questions