OnChange TypeScript decorator

Example fro article https://habrahabr.ru/post/310870/

by Pavel Bogatyrev

TypeScript

class MyClass {
	@OnChange("onFieldChange")
	public mMyField: number = 42;

	onFieldChange(newVal: number): void {
  	  document.body.innerHTML +=
    	"<li>Changing from " + this.mMyField + " to " + newVal + "</li>";
	}
}

function OnChange<T>(callbackName: string): any {
    return (target: Object, propertyKey: string | symbol) => {
      // Необходимо задействовать существующий дескриптор, если он есть.
      // Это позволит объявять несколько декораторов на одном свойстве.
      var descriptor = Object.getOwnPropertyDescriptor(target, propertyKey) 
        || {configurable: true, enumerable: true};
      // Подменяем или объявляем get и set
      var value: T;
      var originalGet = descriptor.get || (() => value);
      var originalSet = descriptor.set || (val => value = val);
      descriptor.get = originalGet;
      descriptor.set = function(newVal: T) {
        // Внимание, если определяем set через function, 
        // то this - текущий экземпляр класса,
        // если через лямбду, то this - Window!!!
        var currentVal = originalGet.call(this);
        if (newVal != currentVal) {
          this[callbackName].call(this, newVal);
        }
        originalSet.call(this, newVal);
      };
      // Объявляем новое свойство, либо обновляем дескриптор
      Object.defineProperty(target, propertyKey, descriptor);
    }
}

var my = new MyClass();
my.mMyField = 43;
my.mMyField = 44;