Search code examples
javascriptbabeljsecmascript-2016

Subclassing a decorated JavaScript Class


I'm decorating a class to provide arguments to it's constructor, the problem arises when I try to subclass this class:

@decorate('foo', 'bar')
class Foo {
    constructor(foo, bar) {}
}

class Bar extends Foo {}


function decorate(foo, bar) {
    return function(ctor) {
        return ctor.bind(null, foo, bar);
    };
}

The above won't work because of the null context passed to the constructor (at least I think that is the root of the issue). When used with Babel, this is the following error: " Object prototype may only be an Object or null: undefined"

Is there any way to both decorate the parent class and extend the child?


Solution

  • Trying to extend a function that has been created via .bind is not going to work for you. Bound functions have tons of special logic around them. Bound functions do not have a .prototype property, which means extending a bound function would mean there was no prototype chain to follow. The proper way to implement this decorator would be to do

    function decorate(foo, bar) {
      return ctor => class extends ctor {
        constructor(...args){
          super(foo, bar, ...args);
        }
      };
    }