<h2 dir="auto">Bug Report</h2>
<p dir="auto"><strong>Current Behavior</strong><br>
let a = {1: 'one', 2: 'two', 3:'three'};<br>
const {1:val, ...aWithoutOne} = a;<br>
console.log(val); // prints 'one'<br>
console.log(aWithoutOne); // Expects {2:'two', 3:'three'} , gets {1: 'one', 2: 'two', 3:'three'};</p>
<p dir="auto"><strong>Input Code</strong><br>
Run the code above in JSBin against Javascript and ES6/Babel to see the difference.</p>
<p dir="auto"><strong>Expected behavior/code</strong><br>
A clear and concise description of what you expected to happen (or code).<br>
The problem is because ObjectWithoutProperties uses a for(key in obj) loop and compares with the keys sent. Since the key here is a number and for..in returns string, the behavior is incorrect. It is different from a v8 implementation. Making matters worse, <code class="notranslate">val</code> is set correctly, which made it harder to debug.</p>
<p dir="auto"><strong>Possible Solution</strong></p>

<p dir="auto">Convert the keys to string before passing to ObjectWithoutProperties() function</p>
<p dir="auto"><strong>Additional context/Screenshots</strong><br>
Try the code in Babel REPL and observe the output difference in Chrome console from both side.</p>
<h2 dir="auto">Bug Report</h2>
<p dir="auto"><strong>Current Behavior</strong></p>
<p dir="auto">This was discovered a few days ago. We were using three “newer” JavaScript features:</p>
<ul dir="auto">
<li>Object destructuring</li>
<li>Rest properties</li>
<li>Computed property names</li>
</ul>
<p dir="auto">The following line (from the block below):</p>
<p dir="auto"><code class="notranslate">const { [person.id]: excludedPerson, ...includedPeople } = samePeople;</code></p>
<p dir="auto">... will pick off the value and place it in <code class="notranslate">excludedPerson</code>, but fail to exclude that entry in <code class="notranslate">includedPeople</code>. This is only the case if <code class="notranslate">person.id</code> is passed in as a <code class="notranslate">number</code>, but if it is cast to a <code class="notranslate">string</code> then that property is (correctly) omitted in <code class="notranslate">includedPeople</code>.</p>
<p dir="auto"><strong>Input Code</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="const people = {
  21: {
    id: 21,
    name: 'Michelle Rodriguez',
  },
  22: {
    id: 22,
    name: 'Heath Ledger',
  },
  23: {
    id: 23,
    name: 'Jack the Ripper',
  },
};

const id = 21;
const person = people[id];
const samePeople = { ...people };

const { [person.id]: excludedPerson, ...includedPeople } = samePeople;

console.log(excludedPerson, includedPeople);"><pre class="notranslate"><span class="pl-k">const</span> <span class="pl-s1">people</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
  <span class="pl-c1">21</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">id</span>: <span class="pl-c1">21</span><span class="pl-kos">,</span>
    <span class="pl-c1">name</span>: <span class="pl-s">'Michelle Rodriguez'</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-c1">22</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">id</span>: <span class="pl-c1">22</span><span class="pl-kos">,</span>
    <span class="pl-c1">name</span>: <span class="pl-s">'Heath Ledger'</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-c1">23</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">id</span>: <span class="pl-c1">23</span><span class="pl-kos">,</span>
    <span class="pl-c1">name</span>: <span class="pl-s">'Jack the Ripper'</span><span class="pl-kos">,</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">const</span> <span class="pl-s1">id</span> <span class="pl-c1">=</span> <span class="pl-c1">21</span><span class="pl-kos">;</span>
<span class="pl-k">const</span> <span class="pl-s1">person</span> <span class="pl-c1">=</span> <span class="pl-s1">people</span><span class="pl-kos">[</span><span class="pl-s1">id</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
<span class="pl-k">const</span> <span class="pl-s1">samePeople</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> ...<span class="pl-s1">people</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-kos">{</span> <span class="pl-kos">[</span><span class="pl-s1">person</span><span class="pl-kos">.</span><span class="pl-c1">id</span><span class="pl-kos">]</span>: <span class="pl-s1">excludedPerson</span><span class="pl-kos">,</span> ...<span class="pl-s1">includedPeople</span> <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-s1">samePeople</span><span class="pl-kos">;</span>

<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">excludedPerson</span><span class="pl-kos">,</span> <span class="pl-s1">includedPeople</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Expected behavior/code</strong></p>
<p dir="auto">It would be expected that that the Michelle Rodriguez object would be omitted from <code class="notranslate">includedPeople</code> but it is still included in <code class="notranslate">includedPeople</code>.</p>
<p dir="auto"><strong>Babel Configuration (.babelrc, package.json, cli command)</strong></p>
<p dir="auto">This can be replicated here: <a href="https://babeljs.io/repl" rel="nofollow">https://babeljs.io/repl</a></p>
<p dir="auto"><strong>Environment</strong></p>
<p dir="auto">This can be replicated here: <a href="https://babeljs.io/repl" rel="nofollow">https://babeljs.io/repl</a></p>
<p dir="auto"><strong>Possible Solution</strong></p>
<p dir="auto">Babel spits out the following code in order to omit properties from the <code class="notranslate">rest</code> object:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function _objectWithoutProperties(obj, keys) {
  var target = {};
  for (var i in obj) {
    if (keys.indexOf(i) &gt;= 0) continue;

    // Excludes properties on the prototype chain.
    if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
    target[i] = obj[i];
  }
  return target;
}"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">_objectWithoutProperties</span><span class="pl-kos">(</span><span class="pl-s1">obj</span><span class="pl-kos">,</span> <span class="pl-s1">keys</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">var</span> <span class="pl-s1">target</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
  <span class="pl-k">for</span> <span class="pl-kos">(</span><span class="pl-k">var</span> <span class="pl-s1">i</span> <span class="pl-k">in</span> <span class="pl-s1">obj</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-s1">keys</span><span class="pl-kos">.</span><span class="pl-en">indexOf</span><span class="pl-kos">(</span><span class="pl-s1">i</span><span class="pl-kos">)</span> <span class="pl-c1">&gt;=</span> <span class="pl-c1">0</span><span class="pl-kos">)</span> <span class="pl-k">continue</span><span class="pl-kos">;</span>

    <span class="pl-c">// Excludes properties on the prototype chain.</span>
    <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">.</span><span class="pl-c1">hasOwnProperty</span><span class="pl-kos">.</span><span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-s1">obj</span><span class="pl-kos">,</span> <span class="pl-s1">i</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-k">continue</span><span class="pl-kos">;</span>
    <span class="pl-s1">target</span><span class="pl-kos">[</span><span class="pl-s1">i</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">obj</span><span class="pl-kos">[</span><span class="pl-s1">i</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">target</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">If <code class="notranslate">person.id</code> is passed as a number (i.e. just as it is), then the <code class="notranslate">keys.indexOf(i) &gt;= 0</code> check fails, since the <code class="notranslate">for..in</code> loop will return the keys as <code class="notranslate">strings</code>. The <code class="notranslate">keys</code> parameter will be an <code class="notranslate">Array</code> of just one <code class="notranslate">number</code> (as per the above code), e.g. <code class="notranslate">'21'</code> will not be found inside <code class="notranslate">[21]</code>. Therefore the property does not get excluded from <code class="notranslate">target</code> and ends up in the <code class="notranslate">rest</code> object.</p>
<p dir="auto">But if I cast to a <code class="notranslate">string</code>, e.g. <code class="notranslate">`${person.id}`</code>, <code class="notranslate">String(person.id)</code>, <code class="notranslate">person.id + ''</code>, <code class="notranslate">Number(person.id).toString()</code>, then the condition goes through.</p>
<p dir="auto"><strong>Additional context/Screenshots</strong></p>
<p dir="auto">We ended up going with Lodash's <code class="notranslate">omit</code> in order to omit the chosen property, but a fix that worked was simply casting <code class="notranslate">person.id</code> to a <code class="notranslate">string</code>, e.g.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="const id = 21;
const person = people[id];
const samePeople = { ...people };

const personId = `${person.id}`;

const { [personId]: excludedPerson, ...includedPeople } = samePeople;"><pre class="notranslate"><span class="pl-k">const</span> <span class="pl-s1">id</span> <span class="pl-c1">=</span> <span class="pl-c1">21</span><span class="pl-kos">;</span>
<span class="pl-k">const</span> <span class="pl-s1">person</span> <span class="pl-c1">=</span> <span class="pl-s1">people</span><span class="pl-kos">[</span><span class="pl-s1">id</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
<span class="pl-k">const</span> <span class="pl-s1">samePeople</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> ...<span class="pl-s1">people</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-s1">personId</span> <span class="pl-c1">=</span> <span class="pl-s">`<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">person</span><span class="pl-kos">.</span><span class="pl-c1">id</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-kos">{</span> <span class="pl-kos">[</span><span class="pl-s1">personId</span><span class="pl-kos">]</span>: <span class="pl-s1">excludedPerson</span><span class="pl-kos">,</span> ...<span class="pl-s1">includedPeople</span> <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-s1">samePeople</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">At that point the omission works correctly.</p>
<p dir="auto">The code seems to work correctly in the Chrome Console and the Node.js REPL, but fails when Babel transpiles it.</p>