Issue 1:
Object Spread Initializers is a proposed feature of ES2016 and is very useful when writing Redux reducers. The syntax is supported in babel, but when using the feature in Visual Studio Code it will mark the spread operator as a syntax error.

See: https://github.com/sebmarkbage/ecmascript-rest-spread/blob/master/Spread.md

for more information of the feature.

It would be very nice if Visual Studio Code did not mark the use of this feature as an error with a red squiggly.

The current behavior in Visual Studio Code is also described in Issue #1640

Issue 2:
es7 proposal : https://github.com/sebmarkbage/ecmascript-rest-spread

Spread properties

Typing

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 :

var obj = { x: 1, y: 2};
var obj1 = {...obj, z: 3, y: 4}; // not an error

I have a very naive type check algorithm for a similar feature (JSXSpreadAttribute) in my little jsx-typescript fork: I just copy the properties of the spread object in the properties table when I encounter a spread object, and override those property if I encounter a declaration with a similar name.

Emitting

jstransform use Object.assign, babel introduce a shim:

var _extends = Object.assign || function (target) { for (var i = 1; i < 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; };

We could either force the presence of assign function on ObjectConstructor interface, or provide a similar function (with a different name).

I think that the optimal solution would be to not emit any helper in es6 target (or if Object.assign is defined), and to emit an helper function for es5, es3.

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 < 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 });

Rest properties

Typing

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 :

var obj = {x:1, y: 1, z: 1};
var {z, ...obj1} = obj;
obj1// {x: number; y:number};

If the destructuring assignment has an index declaration, the result has also a similar index declaration:

var obj: { [string: string]: string };
var {[excludedId], ...obj1} = obj;
obj1// { [string: string]: string };

new/call declarations are obviously not captured:

var obj: { (): void; property: string};
var { ...obj1} = obj;
obj1// { property: string };

Emitting

It is not possible to emit rest properties without an helper function, this one is from babel:

var obj = {x:1, y: 1, z: 1};
var {z, ...obj1} = obj;

var __objectWithoutProperties = function(obj, keys) {
var target = {};
for (var i in obj) {
if (keys.indexOf(i) >= 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, ["z"]);

Edit: added some little typing/emitting example