Search code examples
javascripttypescriptdecoratores6-proxy

Maximum call stack size exceeded when replacing prototype with ES6 Proxy


I have a typescript class decorator

export function Profile(config: ProfilerConfig): ClassDecorator {
  return function <TFunction extends Function> (target: TFunction) {
    logToConsole = config.logToConsole || false;
    Object.setPrototypeOf(
      target.prototype,
      new Proxy(target.prototype , handler)
    );
  };
}

And I am trying to replace the prototype with a proxy of the target prototype and I am getting

ERROR RangeError: Maximum call stack size exceeded

But I am not seeing any apparent recursion. When I use

target.prototype = new Proxy(target.prototype , handler)

this does not happen. Any ideas ?


Solution

  • target.prototype = new Proxy(target.prototype , handler)
    

    This sets the prototype of target to a proxy of itself.

    Object.setPrototypeOf(
      target.prototype,
      new Proxy(target.prototype , handler)
    );
    

    This sets the prototype of target.prototype to a proxy of target.prototype. Then you've got a cyclic dependency: Object.getPrototypeOf(target.prototype) == proxy(target.prototype), so when JavaScript tries to walk the prototype chain it will be stuck in an infinite loop of calling the Proxy handler over and over.


    I think Object.setPrototypeOf() doesn't make any sense here anyway. This function is meant to set the prototype of an instance. You seem to be trying to set the prototype of a constructor, i.e. the constructor.prototype object that will be inherited from when creating an instance by new constructor. You need to assign the prototype of the constructor directly as in your first snippet.