-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Description
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 errorI 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