<p dir="auto">Here is the ES7 proposal:<br>
<a href="https://github.com/sebmarkbage/ecmascript-rest-spread">https://github.com/sebmarkbage/ecmascript-rest-spread</a></p>
<p dir="auto">Rest Properties</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // 1
y; // 2
z; // { a: 3, b: 4 }"><pre class="notranslate"><span class="pl-k">let</span> <span class="pl-kos">{</span> x<span class="pl-kos">,</span> y<span class="pl-kos">,</span> ...<span class="pl-s1">z</span> <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">x</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">y</span>: <span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">a</span>: <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">b</span>: <span class="pl-c1">4</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-s1">x</span><span class="pl-kos">;</span> <span class="pl-c">// 1</span>
<span class="pl-s1">y</span><span class="pl-kos">;</span> <span class="pl-c">// 2</span>
<span class="pl-s1">z</span><span class="pl-kos">;</span> <span class="pl-c">// { a: 3, b: 4 }</span></pre></div>
<p dir="auto">Spread Properties</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="let n = { x, y, ...z };
n; // { x: 1, y: 2, a: 3, b: 4 }"><pre class="notranslate"><span class="pl-k">let</span> <span class="pl-s1">n</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> x<span class="pl-kos">,</span> y<span class="pl-kos">,</span> ...<span class="pl-s1">z</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-s1">n</span><span class="pl-kos">;</span> <span class="pl-c">// { x: 1, y: 2, a: 3, b: 4 }</span></pre></div>
<p dir="auto">es7 proposal : <a href="https://github.com/sebmarkbage/ecmascript-rest-spread">https://github.com/sebmarkbage/ecmascript-rest-spread</a></p>
<h2 dir="auto">Spread properties</h2>
<h3 dir="auto">Typing</h3>
<p dir="auto">In my opinion the goal of this method is to be able to duplicate an object and changing some props, so I think it's particularly important in this case to not check duplicate property declaration :</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var obj = { x: 1, y: 2};
var obj1 = {...obj, z: 3, y: 4}; // not an error"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">obj</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">x</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">y</span>: <span class="pl-c1">2</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">obj1</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>...<span class="pl-s1">obj</span><span class="pl-kos">,</span> <span class="pl-c1">z</span>: <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">y</span>: <span class="pl-c1">4</span><span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-c">// not an error</span></pre></div>
<p dir="auto">I have a very naive <a href="https://github.com/fdecampredon/jsx-typescript/blob/3c692cbb80622b74d1b308b3c5dcab6b993b4111/src/compiler/checker.ts#L5665-L5671">type check algorithm</a> for a similar feature (<code class="notranslate">JSXSpreadAttribute</code>) in my little <code class="notranslate">jsx-typescript</code> fork: I just copy the properties of the <em>spread object</em> in the properties table when I encounter a spread object, and override those property if I encounter a declaration with a similar name.</p>
<h3 dir="auto">Emitting</h3>
<p dir="auto"><a href="https://github.com/facebook/jstransform/">jstransform</a> use <code class="notranslate">Object.assign</code>, <a href="https://babeljs.io/" rel="nofollow">babel</a> introduce a shim:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var _extends = Object.assign || function (target) { for (var i = 1; i &lt; arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">_extends</span> <span class="pl-c1">=</span> <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-c1">assign</span> <span class="pl-c1">||</span> <span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-s1">target</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-c1">=</span> <span class="pl-c1">1</span><span class="pl-kos">;</span> <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-smi">arguments</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-s1">i</span><span class="pl-c1">++</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-k">var</span> <span class="pl-s1">source</span> <span class="pl-c1">=</span> <span class="pl-smi">arguments</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">for</span> <span class="pl-kos">(</span><span class="pl-k">var</span> <span class="pl-s1">key</span> <span class="pl-k">in</span> <span class="pl-s1">source</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-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">source</span><span class="pl-kos">,</span> <span class="pl-s1">key</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-s1">target</span><span class="pl-kos">[</span><span class="pl-s1">key</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">source</span><span class="pl-kos">[</span><span class="pl-s1">key</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">return</span> <span class="pl-s1">target</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">We could either force the presence of <code class="notranslate">assign</code> function on <code class="notranslate">ObjectConstructor</code> interface, or provide a similar function (with a different name).</p>
<p dir="auto">I think that the optimal solution would be to not emit any helper in <code class="notranslate">es6</code> target (or if <code class="notranslate">Object.assign</code> is defined), and to emit an helper function for <code class="notranslate">es5</code>, <code class="notranslate">es3</code>.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var obj = { x: 1, y: 2};
var obj1 = {...obj, z: 3};

/// ES6 emit
var obj = {x: 1, y: 2};
var obj1= Object.assign({}, obj, { z: 3 });

//ES3 emit
var __assign = function (target) { 
    for (var i = 1; i &lt; arguments.length; i++) { 
        var source = arguments[i]; 
        for (var key in source) { 
            if (Object.prototype.hasOwnProperty.call(source, key)) { 
                target[key] = source[key];
            } 
        } 
    } 
    return target; 
};

var obj = {x: 1, y: 2};
var obj1= __assign({}, obj, { z: 3 });"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">obj</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">x</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">y</span>: <span class="pl-c1">2</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">obj1</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>...<span class="pl-s1">obj</span><span class="pl-kos">,</span> <span class="pl-c1">z</span>: <span class="pl-c1">3</span><span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-c">/// ES6 emit</span>
<span class="pl-k">var</span> <span class="pl-s1">obj</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-c1">x</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">y</span>: <span class="pl-c1">2</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">obj1</span><span class="pl-c1">=</span> <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">assign</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-s1">obj</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">z</span>: <span class="pl-c1">3</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">//ES3 emit</span>
<span class="pl-k">var</span> <span class="pl-en">__assign</span> <span class="pl-c1">=</span> <span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-s1">target</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-c1">=</span> <span class="pl-c1">1</span><span class="pl-kos">;</span> <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-smi">arguments</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-s1">i</span><span class="pl-c1">++</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> 
        <span class="pl-k">var</span> <span class="pl-s1">source</span> <span class="pl-c1">=</span> <span class="pl-smi">arguments</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">for</span> <span class="pl-kos">(</span><span class="pl-k">var</span> <span class="pl-s1">key</span> <span class="pl-k">in</span> <span class="pl-s1">source</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-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">source</span><span class="pl-kos">,</span> <span class="pl-s1">key</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> 
                <span class="pl-s1">target</span><span class="pl-kos">[</span><span class="pl-s1">key</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">source</span><span class="pl-kos">[</span><span class="pl-s1">key</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">return</span> <span class="pl-s1">target</span><span class="pl-kos">;</span> 
<span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-k">var</span> <span class="pl-s1">obj</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-c1">x</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">y</span>: <span class="pl-c1">2</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">obj1</span><span class="pl-c1">=</span> <span class="pl-en">__assign</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-s1">obj</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">z</span>: <span class="pl-c1">3</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<h2 dir="auto">Rest properties</h2>
<h3 dir="auto">Typing</h3>
<p dir="auto">For simple object the new type is a subtype of the assignation that does not contains properties that has been captured before the rest properties :</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var obj = {x:1, y: 1, z: 1};
var {z, ...obj1} = obj;
obj1// {x: number; y:number};"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">obj</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-c1">x</span>:<span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">y</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">z</span>: <span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-kos">{</span>z<span class="pl-kos">,</span> ...<span class="pl-s1">obj1</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">obj1</span><span class="pl-c">// {x: number; y:number};</span></pre></div>
<p dir="auto">If the destructuring assignment has an index declaration, the result has also a similar index declaration:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var obj: { [string: string]: string };
var {[excludedId], ...obj1} = obj;
obj1// { [string: string]: string };"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">obj</span>: <span class="pl-kos">{</span> <span class="pl-kos">[</span><span class="pl-s1">string</span>: <span class="pl-smi">string</span><span class="pl-kos">]</span>: <span class="pl-smi">string</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-kos">{</span><span class="pl-kos">[</span><span class="pl-s1">excludedId</span><span class="pl-kos">]</span><span class="pl-kos">,</span> ...<span class="pl-s1">obj1</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">obj1</span><span class="pl-c">// { [string: string]: string };</span></pre></div>
<p dir="auto">new/call declarations are obviously not captured:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var obj: { (): void; property: string};
var { ...obj1} = obj;
obj1// { property: string };"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">obj</span>: <span class="pl-kos">{</span> <span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-smi"><span class="pl-k">void</span></span><span class="pl-kos">;</span> <span class="pl-c1">property</span>: <span class="pl-smi">string</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-kos">{</span> ...<span class="pl-s1">obj1</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">obj1</span><span class="pl-c">// { property: string };</span></pre></div>
<h3 dir="auto">Emitting</h3>
<p dir="auto">It is not possible to emit <em>rest properties</em> without an helper function, this one is from babel:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var obj = {x:1, y: 1, z: 1};
var {z, ...obj1} = obj;"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">obj</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-c1">x</span>:<span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">y</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">z</span>: <span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-kos">{</span>z<span class="pl-kos">,</span> ...<span class="pl-s1">obj1</span><span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-s1">obj</span><span class="pl-kos">;</span></pre></div>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var __objectWithoutProperties = function(obj, keys) {
    var target = {};
    for (var i in obj) {
        if (keys.indexOf(i) &gt;= 0) continue;
        if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
        target[i] = obj[i];
    }
    return target;
};

var obj = {x:1, y: 1, z: 1};
var z = obj.z;
var obj1 = __objectWithoutProperties(obj, [&quot;z&quot;]);"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-en">__objectWithoutProperties</span> <span class="pl-c1">=</span> <span class="pl-k">function</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-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><span class="pl-kos">;</span>

<span class="pl-k">var</span> <span class="pl-s1">obj</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-c1">x</span>:<span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">y</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">z</span>: <span class="pl-c1">1</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">z</span> <span class="pl-c1">=</span> <span class="pl-s1">obj</span><span class="pl-kos">.</span><span class="pl-c1">z</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">obj1</span> <span class="pl-c1">=</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-kos">[</span><span class="pl-s">"z"</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><em>Edit: added some little typing/emitting example</em></p>