<p dir="auto">(with a built-in class, or indeed a class defined using the native <code class="notranslate">class</code> syntax)</p>
<h3 dir="auto">Input Code</h3>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="const headers = new class extends Headers {}"><pre class="notranslate"><span class="pl-k">const</span> <span class="pl-s1">headers</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-k">class</span> <span class="pl-k">extends</span> <span class="pl-v">Headers</span> <span class="pl-kos">{</span><span class="pl-kos">}</span></pre></div>
<h3 dir="auto">Link to repl</h3>
<p dir="auto"><a href="http://babeljs.io/repl/#?babili=false&amp;evaluate=true&amp;lineWrap=false&amp;presets=es2015&amp;targets=&amp;browsers=&amp;builtIns=false&amp;code=const%20headers%20%3D%20new%20class%20extends%20Headers%20%7B%7D&amp;experimental=false&amp;loose=false&amp;spec=false&amp;playground=true" rel="nofollow">babel repl</a></p>
<h3 dir="auto">Expected Behavior</h3>
<p dir="auto">generate code that works, as the input code does in browser</p>
<h3 dir="auto">Current Behavior</h3>
<p dir="auto">the generated code does not work (says `Constructor Headers requires 'new')</p>
<h3 dir="auto">Context</h3>
<p dir="auto">i just need to add a couple of methods in one place to a class that's already defined as a class (and as such requires new).</p>
<p dir="auto">Current Babel transform, when it comes to call the parent</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function _possibleConstructorReturn(self, call) {
  if (!self) {
    throw new ReferenceError(&quot;this hasn't been initialised - super() hasn't been called&quot;);
  }
  return call &amp;&amp; (typeof call === &quot;object&quot; || typeof call === &quot;function&quot;) ? call : self;
}"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">_possibleConstructorReturn</span><span class="pl-kos">(</span><span class="pl-s1">self</span><span class="pl-kos">,</span> <span class="pl-s1">call</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">self</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">throw</span> <span class="pl-k">new</span> <span class="pl-v">ReferenceError</span><span class="pl-kos">(</span><span class="pl-s">"this hasn't been initialised - super() hasn't been called"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
  <span class="pl-k">return</span> <span class="pl-s1">call</span> <span class="pl-c1">&amp;&amp;</span> <span class="pl-kos">(</span><span class="pl-k">typeof</span> <span class="pl-s1">call</span> <span class="pl-c1">===</span> <span class="pl-s">"object"</span> <span class="pl-c1">||</span> <span class="pl-k">typeof</span> <span class="pl-s1">call</span> <span class="pl-c1">===</span> <span class="pl-s">"function"</span><span class="pl-kos">)</span> ? <span class="pl-s1">call</span> : <span class="pl-s1">self</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">It's a way too poor implementation.</p>
<p dir="auto">If we take the current basic ES6 compat syntax:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class List extends Array {}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">List</span> <span class="pl-k">extends</span> <span class="pl-v">Array</span> <span class="pl-kos">{</span><span class="pl-kos">}</span></pre></div>
<p dir="auto">We'll realize babel does a bad job.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var l = new List();
l instanceof List; // false"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">l</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">List</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-s1">l</span> <span class="pl-k">instanceof</span> <span class="pl-v">List</span><span class="pl-kos">;</span> <span class="pl-c">// false</span></pre></div>
<p dir="auto">The reason is simple: Babel replace the returns and exit, without caring about userland expectations.</p>
<p dir="auto">This is how above basic extend should desugar:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function List() {
  return Object.setPrototypeOf(
    Array.apply(this, arguments),
    List.prototype
  );
}"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-v">List</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">setPrototypeOf</span><span class="pl-kos">(</span>
    <span class="pl-v">Array</span><span class="pl-kos">.</span><span class="pl-en">apply</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">,</span> <span class="pl-smi">arguments</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
    <span class="pl-v">List</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span>
  <span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">It's a very ad-hoc case for the initial example that currently fails, but it's good enough to understand that inheriting the prototype is the least of the problem.</p>
<p dir="auto">Indeed, we have 3 ways to do that within a transpiled code:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// losing the initial prototype
// for polyfilled ES5+ or lower
List.prototype = Object.create(
  Array.prototype,
  {constructor: {
    configurable: true,
    writable: true,
    value: List.prototype
  }}
);

// using a cleaner way
// for ES5+ compliant targets
Object.setPrototypeOf(
  List.prototype,
  Array.prototype
);

// using a cleaner way
// that works well with
// partially polyfilled .setPrototypeOf
List.prototype = Object.setPrototypeOf(
  List.prototype,
  Array.prototype
);"><pre class="notranslate"><span class="pl-c">// losing the initial prototype</span>
<span class="pl-c">// for polyfilled ES5+ or lower</span>
<span class="pl-v">List</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span> <span class="pl-c1">=</span> <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">create</span><span class="pl-kos">(</span>
  <span class="pl-v">Array</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span><span class="pl-c1">constructor</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">configurable</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
    <span class="pl-c1">writable</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
    <span class="pl-c1">value</span>: <span class="pl-v">List</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span>
  <span class="pl-kos">}</span><span class="pl-kos">}</span>
<span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// using a cleaner way</span>
<span class="pl-c">// for ES5+ compliant targets</span>
<span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">setPrototypeOf</span><span class="pl-kos">(</span>
  <span class="pl-v">List</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">,</span>
  <span class="pl-v">Array</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span>
<span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// using a cleaner way</span>
<span class="pl-c">// that works well with</span>
<span class="pl-c">// partially polyfilled .setPrototypeOf</span>
<span class="pl-v">List</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span> <span class="pl-c1">=</span> <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">setPrototypeOf</span><span class="pl-kos">(</span>
  <span class="pl-v">List</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">,</span>
  <span class="pl-v">Array</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span>
<span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Solved the inheritance bit, considering Babel also set the prototype of each constructor,<br>
we need to address cases where a <code class="notranslate">super</code> call might "<em>upgrade</em>" the current context, like it is for <code class="notranslate">HTMLELement</code> or exotic native objects.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// native ES6 static example
class List extends Array {
  constructor(a, b, c) {
    super(a, b);
    this.push(c);
  }
}"><pre class="notranslate"><span class="pl-c">// native ES6 static example</span>
<span class="pl-k">class</span> <span class="pl-v">List</span> <span class="pl-k">extends</span> <span class="pl-v">Array</span> <span class="pl-kos">{</span>
  <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-s1">a</span><span class="pl-kos">,</span> <span class="pl-s1">b</span><span class="pl-kos">,</span> <span class="pl-s1">c</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">super</span><span class="pl-kos">(</span><span class="pl-s1">a</span><span class="pl-kos">,</span> <span class="pl-s1">b</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-s1">c</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">Above case should desugar to something like the follwoing:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function List(a, b, c) {
  // the super bit
  var self = Object.setPrototypeOf(
    Array.call(this, a, b),
    List.prototype
  );
  // the rest with swapped context
  self.push(c);
  // at the end
  return self;
}"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-v">List</span><span class="pl-kos">(</span><span class="pl-s1">a</span><span class="pl-kos">,</span> <span class="pl-s1">b</span><span class="pl-kos">,</span> <span class="pl-s1">c</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-c">// the super bit</span>
  <span class="pl-k">var</span> <span class="pl-s1">self</span> <span class="pl-c1">=</span> <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">setPrototypeOf</span><span class="pl-kos">(</span>
    <span class="pl-v">Array</span><span class="pl-kos">.</span><span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">,</span> <span class="pl-s1">a</span><span class="pl-kos">,</span> <span class="pl-s1">b</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
    <span class="pl-v">List</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span>
  <span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-c">// the rest with swapped context</span>
  <span class="pl-s1">self</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-s1">c</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-c">// at the end</span>
  <span class="pl-k">return</span> <span class="pl-s1">self</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">which is also ad-hoc example code for the previous example.</p>
<p dir="auto">Considering a transpiler will get the arguments part easily right, this is how previous case could be generically transpiled for arguments used in both constructors:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// to make it as generic as possible
function Child() {

  // the super call bit desugar to ...
  var
    instance = Object.getPrototypeOf(Child)
        .apply(this, arguments),
    type = instance ? typeof instance : '',
    // if Parent overwrote its default return
    self = (type === 'object' || type === 'function') ?
      // upgrade the instance to reflect Child constructor
      Object.setPrototypeOf(instance, Child.prototype) :
      // otherwise use the current context as is
      this
  ;

  // at this point, the rest of the constructor
  // should use `self` instead of `this`
  self.push(c);

  // and return `self` reference at the end
  return self;
}"><pre class="notranslate"><span class="pl-c">// to make it as generic as possible</span>
<span class="pl-k">function</span> <span class="pl-v">Child</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>

  <span class="pl-c">// the super call bit desugar to ...</span>
  <span class="pl-k">var</span>
    <span class="pl-s1">instance</span> <span class="pl-c1">=</span> <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">getPrototypeOf</span><span class="pl-kos">(</span><span class="pl-v">Child</span><span class="pl-kos">)</span>
        <span class="pl-kos">.</span><span class="pl-en">apply</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">,</span> <span class="pl-smi">arguments</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
    <span class="pl-s1">type</span> <span class="pl-c1">=</span> <span class="pl-s1">instance</span> ? <span class="pl-k">typeof</span> <span class="pl-s1">instance</span> : <span class="pl-s">''</span><span class="pl-kos">,</span>
    <span class="pl-c">// if Parent overwrote its default return</span>
    <span class="pl-s1">self</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">type</span> <span class="pl-c1">===</span> <span class="pl-s">'object'</span> <span class="pl-c1">||</span> <span class="pl-s1">type</span> <span class="pl-c1">===</span> <span class="pl-s">'function'</span><span class="pl-kos">)</span> ?
      <span class="pl-c">// upgrade the instance to reflect Child constructor</span>
      <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">setPrototypeOf</span><span class="pl-kos">(</span><span class="pl-s1">instance</span><span class="pl-kos">,</span> <span class="pl-v">Child</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">)</span> :
      <span class="pl-c">// otherwise use the current context as is</span>
      <span class="pl-smi">this</span>
  <span class="pl-kos">;</span>

  <span class="pl-c">// at this point, the rest of the constructor</span>
  <span class="pl-c">// should use `self` instead of `this`</span>
  <span class="pl-s1">self</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-s1">c</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

  <span class="pl-c">// and return `self` reference at the end</span>
  <span class="pl-k">return</span> <span class="pl-s1">self</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">The last problem is that modern syntax would use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect" rel="nofollow">Reflect</a> to create any sort of object, instead of old, ES3 friendly, <code class="notranslate">.call</code> or <code class="notranslate">.apply</code> way.</p>
<p dir="auto">Following a past, present, and even future proof approach:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var
  reConstruct = typeof Reflect === 'object' ?
    Reflect.construct :
    function (Parent, args, Child) {
      return Parent.apply(this, args);
    }
;

function Child() {

  // the super call bit
  var
    instance = reConstruct.call(
      this,
      Object.getPrototypeOf(Child),
      arguments,
      Child
    ),
    type = instance ? typeof instance : '',
    self = (type === 'object' || type === 'function') ?
      Object.setPrototypeOf(instance, Child.prototype) :
      this
  ;

  // the rest of the constructor body
  self.push(c);

  // at the end or instead of empty returns
  return self;
}"><pre class="notranslate"><span class="pl-k">var</span>
  <span class="pl-s1">reConstruct</span> <span class="pl-c1">=</span> <span class="pl-k">typeof</span> <span class="pl-v">Reflect</span> <span class="pl-c1">===</span> <span class="pl-s">'object'</span> ?
    <span class="pl-v">Reflect</span><span class="pl-kos">.</span><span class="pl-c1">construct</span> :
    <span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-v">Parent</span><span class="pl-kos">,</span> <span class="pl-s1">args</span><span class="pl-kos">,</span> <span class="pl-v">Child</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
      <span class="pl-k">return</span> <span class="pl-v">Parent</span><span class="pl-kos">.</span><span class="pl-en">apply</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">,</span> <span class="pl-s1">args</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">;</span>

<span class="pl-k">function</span> <span class="pl-v">Child</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>

  <span class="pl-c">// the super call bit</span>
  <span class="pl-k">var</span>
    <span class="pl-s1">instance</span> <span class="pl-c1">=</span> <span class="pl-s1">reConstruct</span><span class="pl-kos">.</span><span class="pl-en">call</span><span class="pl-kos">(</span>
      <span class="pl-smi">this</span><span class="pl-kos">,</span>
      <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">getPrototypeOf</span><span class="pl-kos">(</span><span class="pl-v">Child</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
      <span class="pl-smi">arguments</span><span class="pl-kos">,</span>
      <span class="pl-v">Child</span>
    <span class="pl-kos">)</span><span class="pl-kos">,</span>
    <span class="pl-s1">type</span> <span class="pl-c1">=</span> <span class="pl-s1">instance</span> ? <span class="pl-k">typeof</span> <span class="pl-s1">instance</span> : <span class="pl-s">''</span><span class="pl-kos">,</span>
    <span class="pl-s1">self</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">type</span> <span class="pl-c1">===</span> <span class="pl-s">'object'</span> <span class="pl-c1">||</span> <span class="pl-s1">type</span> <span class="pl-c1">===</span> <span class="pl-s">'function'</span><span class="pl-kos">)</span> ?
      <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">setPrototypeOf</span><span class="pl-kos">(</span><span class="pl-s1">instance</span><span class="pl-kos">,</span> <span class="pl-v">Child</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">)</span> :
      <span class="pl-smi">this</span>
  <span class="pl-kos">;</span>

  <span class="pl-c">// the rest of the constructor body</span>
  <span class="pl-s1">self</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-s1">c</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

  <span class="pl-c">// at the end or instead of empty returns</span>
  <span class="pl-k">return</span> <span class="pl-s1">self</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">Above solution would work with userland, exotic, or DOM constructors, and in both native and transpiled engines.</p>