Skip to content

Support proposed ES Rest/Spread properties #2103

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 :

varobj={x: 1,y: 2};varobj1={...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(vari=1;i<arguments.length;i++){varsource=arguments[i];for(varkeyinsource){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}returntarget;};

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.

varobj={x: 1,y: 2};varobj1={...obj,z: 3};/// ES6 emitvarobj={x: 1,y: 2};varobj1=Object.assign({},obj,{z: 3});//ES3 emitvar__assign=function(target){for(vari=1;i<arguments.length;i++){varsource=arguments[i];for(varkeyinsource){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}returntarget;};varobj={x: 1,y: 2};varobj1=__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 :

varobj={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:

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

new/call declarations are obviously not captured:

varobj: {(): 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:

varobj={x:1,y: 1,z: 1};var{z, ...obj1}=obj;
var__objectWithoutProperties=function(obj,keys){vartarget={};for(variinobj){if(keys.indexOf(i)>=0)continue;if(!Object.prototype.hasOwnProperty.call(obj,i))continue;target[i]=obj[i];}returntarget;};varobj={x:1,y: 1,z: 1};varz=obj.z;varobj1=__objectWithoutProperties(obj,["z"]);

Edit: added some little typing/emitting example

Metadata

Metadata

Labels

CommittedThe team has roadmapped this issueES NextNew featurers for ECMAScript (a.k.a. ESNext)FixedA PR has been merged for this issueSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions