'Decorator isn't getting triggered in typescript project

I have @OnChange decorator which receives a callback after the value of the property is triggered.

export interface SimpleChange<T> {
    firstChange: boolean;
    previousValue: T;
    currentValue: T;
    isFirstChange: () => boolean;
}

export interface CallBackFunction<T> {
    (value: T, change?: SimpleChange<T>): void;
}

export function OnChange<T = any>(callback: CallBackFunction<T> | string) {
    const cachedValueKey = Symbol('cachedValue');
    const isFirstChangeKey = Symbol('isFirstChange');

    return (target: any, key: PropertyKey) => {
        console.log(`@OnChange called on '${ String(key) }' from '${ target.constructor.name }'`);
        const callBackFn: CallBackFunction<T> = typeof callback === 'string' ? target[callback] : callback;
        if (!callBackFn) {
            throw new Error(`Cannot find method ${ callback } in class ${ target.constructor.name }`);
        }

        Object.defineProperty(target, key, {
            set: function(value) {
                this[isFirstChangeKey] = this[isFirstChangeKey] === undefined;

                if (!this[isFirstChangeKey] && this[cachedValueKey] === value) {
                    return;
                }

                const oldValue = this[cachedValueKey];
                this[cachedValueKey] = value;

                const change: SimpleChange<T> = {
                    firstChange: !!this[isFirstChangeKey],
                    previousValue: oldValue,
                    currentValue: value,
                    isFirstChange: () => !!this[isFirstChangeKey]
                };
                this[isFirstChangeKey] = false;
                callBackFn.call(this, this[cachedValueKey], change);
            },
            get: function() {
                return this[cachedValueKey];
            }
        });
    };
}

Here's the class that using it:

export class Component extends BaseComponent {
   @OnChange<number>(function (value, changes) {
      console.log(value)
   })
   height: number = 0;

   calculateHeight(minHeight, maxHeight, ratio) {
      // this not triggering the @OnChange decorator
      this.height += 100; // just for demo purposes
   }
}
{
  "compilerOptions": {
    "lib": ["es2018", "DOM"],
    "module": "CommonJS",
    "target": "ES2020",
    "types": ["jest", "node"],
    "outDir": "build",
    "moduleResolution": "node",
    "declaration": true,
    "declarationMap": true,
    "strict": true,
    "noUnusedLocals": true,
    "noImplicitReturns": true,
    "esModuleInterop": true,
    "inlineSourceMap": true,
    "inlineSources": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "useDefineForClassFields": false,
    "plugins": [
      {
        "name": "tslint-language-service",
        "alwaysShowRuleFailuresAsWarnings": false,
        "ignoreDefinitionFiles": true,
        "disableNoUnusedVariableRule": false,
        "supressWhileTypeErrorsPresent": false,
        "mockTypeScriptVersion": false
      }
    ]
  },
  "include": ["src/**/*.ts"]
}

Update: Seems like the debugger is unable to reach: Object.defineProperty it simply doesn't see it.

I have other decorator inside this project and it does work as needed.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source