Search code examples
typescripttypescript-decorator

Dynamic setter from decorator - Typescript complains about read-only property


Consider the following code:

function configurable(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    descriptor.set = (n: number) => {
        target[`_${propertyKey}`] = n * 100;
    };
}

class Test {
    _prop: number = 10;

    @configurable
    get prop(): number {
        return this.prop;
    }
}

const t = new Test();
t.prop = 100;

It's a silly example where I am trying to dynamically add a setter with a decorator, but typescript complains about t.prop be read-only


Solution

  • The following code might help you

    function configurable(multiplierFactor: number) { 
        return function (target, propertyKey: string) {
          const privatePropName = `_${propertyKey}`;
    
          Object.defineProperty(target, propertyKey, {
              configurable: false,
              get: function (this) {
                  return this[privatePropName];
              },
              set: function (this, value) {
                this[privatePropName] = value * multiplierFactor;
              },
          });
        }
    }
    
    class Test {
        @configurable(10)
        prop: number = 1;
    }
    
    const t = new Test();
    console.log(t.prop) // 10
    t.prop = 20;
    console.log(t.prop) // 200