TypeScript Design Meeting Notes: 6/6/2014

Topics: Language Specification
Coordinator
Jun 24, 2014 at 6:53 PM
Edited Jun 25, 2014 at 5:18 PM
ES6 Status
Focus for next feature set
  • Spread
  • Destructuring
ES6 Status

ES6 ratification has been delayed until June 2015. This should not change the set of features, though we're seeing changes land even now, like the new module syntax and the removal of comprehensions.

Proposal for our focus is on features we can downlevel compile (like classes). Because it will take a while for ES6 to be natively supported broadly, the downlevel compilation story will stay a pretty powerful feature for TypeScript.

Looks like these are good candidates:

Arrow functions, default function params, rest params, spread call, spread array, class, class expressions, For...of loops over arrays, template strings, and destructuring.

Spread

Spread array:

Example: [1, 2, ...items, 4, ...moreitems]

Appears to be trivial, we just need to emit: [1, 2].concat(items, [3], moreitems) or similar pattern.

If it starts with the spread, then do items.concat([1, 2], ...)

For spread with functions:

Codegen of f(...items) becomes f.apply(void 0, items) // strict mode, otherwise pass 'this'

We may need to create an __apply of our own for method invocation.
__apply(obj, method, args) {
  obj[method].apply(obj, args);
}

__apply(obj, "foo", items);
Typechecking these calls needs a flexible approach. Key idea is that we need to check arity and types of what we know.
f(1, 2, ...items, 3, ...more): f(T, T, BCT(...items, 3, ...more))
Need to explore this more closely to understand impact.

Destructuring
var [x,y] = myFun();
Codegen:
var __a = myFun();  // fresh var __a
var x = __a[0];
var y = __a[1];
Type annotations:
var {x: myX, y: myY}: {x: …; y: …} = myPoint();  // {x: myX} is a ES6 destructuring with renaming
If type annotations were inline with the destructuring, then you'd get two uses of colon. One for type and one for rename:
var {x: myX: number} = ...;  // ugh
Probably means we'd want to move the type annotation beside instead of inline.
Jun 25, 2014 at 8:01 AM
Edited Jun 25, 2014 at 8:02 AM
ES6 ratification has been delayed until June 2105.
Until 2105! OMG, I hope not. :*( I can't wait that long! Good news for the next generation I guess. ;)
Jun 25, 2014 at 9:07 AM
There is a chicken and egg problem here: now that the module system is supposed to be feature complete, implementations are needed, so that users can get experience, and implementers can report back with issues before the spec is published.

I do recall that TypeScript was hit by the awkward module spec process, but I think it is time to try again. Currently, one can use other ES6 transpilers to get uptodate module system but no types, or use TS and get types but an older module system.

In addition to ES6 features with easy translations, please also consider an ES6 target.

That way, TS can provide typing, and other transpilers and shims (see https://github.com/addyosmani/es6-tools ) can take care of the feature translations until engines have caught up with the spec.
Jun 25, 2014 at 11:12 AM
Hi Jon,

Thanks again for sharing these notes.

Can I ask where the team is on the let and const keywords? I may have missed an earlier thing about this, if so, sorry.

Cheers,
Mark
Jun 25, 2014 at 11:55 AM
destructuring in import statement could be cool :
import { readFileSync, writeFileSync} = require('fs');
Jun 25, 2014 at 2:18 PM
jamesnw wrote:
ES6 ratification has been delayed until June 2105.
Until 2105! OMG, I hope not. :*( I can't wait that long! Good news for the next generation I guess. ;)
You mean the next, next, next generation. This is terrible news! I'll definitely have retired by then!
Jun 25, 2014 at 2:36 PM
On a more serious note, the stuff about spread seems reasonable, but how would you handle the last two cases illustrated here:
Apply for new

Example: In ES5 it is not possible to compose new with apply (in ES5 terms apply does a [[Call]] and not a [[Construct]]). In ES6 the spread syntax naturally supports >this:
var dateFields = readDateFields(database);
var d = new Date(...dateFields);
A better push

Example: push is often used to push an array to the end of an existing array. In ES5 this is often done as:
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Append all items from arr2 onto arr1
Array.prototype.push.apply(arr1, arr2);
In ES6 with spread this becomes:
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);
Coordinator
Jun 25, 2014 at 5:11 PM
Just to clarify, we're still planning to align with ES6. Its delay just changes what features we want to land first.

@clausreinke

We are considering an ES6 target and likely will add one in a future release.

@markrendle

We're still planning to doing let/const but not as a polyfill/downlevel. This means we'd only support them in ES6 output mode.

@MgSam

The first example sounds like a good question for the design team. It's not immediately obvious to me what the polyfill is here. I'd be curious to see what other ES6 compilers do.

The second example I think falls out from the codegen we described. Is there something I'm missing?
Jun 25, 2014 at 5:18 PM
@jonturner The codegen you showed in the design notes only covers array declaration. It seems like to support pushing a spread the compiler would have to specifically have to look for Array.push being used with a spread and then create codegen similar to what Mozilla demonstrates (or rewrite it to use concat instead). Having the compiler special case a certain method like that seems like a slippery slope.

Also, @jamesnw and I were making a joke about the fact that you wrote ES6 has been pushed back to June 2105, aka 91 years from now.
Coordinator
Jun 25, 2014 at 5:20 PM
Ha! I totally missed that :p Fixed now.

I agree that special casing is a slippery slope. We should keep examples like this in mind to make sure we have a general codegen that works across any of the types of invocations ES6 will see.
Jun 26, 2014 at 2:46 PM
Edited Jun 26, 2014 at 2:46 PM
For spread with new, esnext has a pretty interesting approach, however idk if that can be compatible with ES3.