5

I'm proxying methods using the following wrapper:

  public static wrap(target) {
    function construct(constructor, args) {
      const c: any = function(this) {
        return constructor.apply(this, args);
      };

      c.prototype = constructor.prototype;
      return new c();
    }

    const f = (...args) => {
      const instance = construct(target, args);

      const descriptors = getMethodDescriptors(target, instance);

      return new Proxy<T>(
        instance,
        new SomeProxyHandler(descriptors)
      );
    };

    f.prototype = target.prototype;
    return f;
  }

This has worked well when wrapping classes which are compiled down to ES5 but now I'm trying to target ES6 I'm getting errors at constructor.apply(this, args) saying that:

TypeError: Class constructor OneOfMyClasses cannot be invoked without 'new'

How can I fix this code so wrap can proxy classes whatever the JavaScript target and maintain the correct prototype chain?

1

1 Answer 1

7
+300

The easiest way would be spread syntax

const instance = new target(...args);

but you can also use Reflect.construct:

const instance = Reflect.construct(target, args);

This will even be necessary if your wrapped classes are supposed to be extensible, you then will have to make use of new.target:

const instance = Reflect.construct(target, args, new.target);

Btw, your f wrapper should be a proper function not an arrow function, as those cannot be called with new (and don't have new.target). Or maybe even simpler (working better with static methods and inheritance), just wrap the whole target class itself in a Proxy and use its construct trap.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.