alignment with es6 module system?

Topics: General, Language Specification
Jun 11, 2013 at 3:18 PM
ES modules seem to be stabilizing (see 4.10 in the May tc39 meeting notes, as well as the updated wiki links in there), though sadly with lexical modules delayed to ES7.
  1. What are your plans for aligning the TS and ES6/7 module systems?
  2. Have the practical issues encountered by TS users been addressed in the ES6 design?
Jun 11, 2013 at 4:34 PM
We had hoped to see modules converge in TC39 sooner so that we could align fully with the ES6 proposals in 1.0. However, given the current state of the ES6 modules proposal and our desire to stabilize TypeScript 1.0, our current plan is:
  1. TypeScript 1.0 will continue to have internal modules, which are no longer part of ES6. These may be related to future ES7 lexical modules, but it's speculative to say at this point. They are a sugar for IIFE patterns in JavaScript that is important in practice in TypeScript for aligning value and type namespacing in a declarative way.
  2. TypeScript 1.0 will have external modules using the "import http = require('http')" syntax that is currently in the TypeScript specification. In 0.9, we have updated this to handle "export =" patterns so that TypeScript can conveniently express AMD/CommonJS patterns using statically checked declarative syntax. This is semantically very close to ES6 modules, but the import syntax has some differences. TypeScript is more closely aligned with AMD/CommonJS, as it codegens to target these loaders instead of to a separate loader with different behavior as is the case for ES6. As pointed out in the TC39 notes you linked above, I continue to be concerned about the "export default" divergence from AMD/CommonJS, which is of course also a divergence from what TypeScript 1.0 will offer.
  3. TypeScipt 1.0 will support the "module 'foo' { ... }" syntax from ES6 only in "declare module"s used for typing JavaScript components. This syntax in ES6 is primarily motivated by being a target for concatenation tools, and so is not needed in TypeScript (concatenation works at the level of the JavaScript code using AMD/CommonJS in TypeScript). This part of the ES6 design is also the least proven so far.
  4. TypeScript post-1.0 will support ES6 module syntax once it has fully stabilized. Similar to other ES6 features, we will be layering in increasing pieces of ES6 syntax, and allowing many of them to be used targeting ES3/5 where the code generation can be done in a simple and clean way. Where it can't we will only allow use of the constructs when targeting ES6, as is done for "get/set" accessors in TypeScript today for ES5. Given "export default", ES6 modules may unfortunately not be compilable to ES3/5 in a simple and clean way.
Jun 12, 2013 at 2:29 PM
Thanks for the info! I understand that the delays and redesigns of ES6 modules -not to mention the parts now postponed to ES7- have made it difficult to match ES6 while making progress with TS. Could you elaborate on why export default causes more compilation trouble than export = (the meeting notes suggest static checking is a problem, but your point 2 includes "statically checked", and TS has more static interface info than other implementations)?

Nevertheless, it seems odd to have a TS1.0 (the first post-preview release) with incompatible module syntax for the parts shared between ES6 and TS. Is there no hope of aligning the syntax in time for TS1.0? It sounds as if you are not confident about ES6 module syntax stability yet.

Also, since ES6 seems to focus on loaders and configuration over lexical modules, what are your plans for supporting those aspects of ES6?
Jun 17, 2013 at 7:19 PM
clausreinke wrote:
Could you elaborate on why export default causes more compilation trouble than export = (the meeting notes suggest static checking is a problem, but your point 2 includes "statically checked", and TS has more static interface info than other implementations)?
IMO, 'export = ' is more flexible than export default (I suspect you meant it would be used in statement like this: export default class Foo{}, that mean to export the class Foo from the module) as you`re able to export an instance of any class, not just a class reference.
Jun 18, 2013 at 12:40 PM
Edited Jun 18, 2013 at 12:41 PM
  1. I'm a little concerned about "This syntax in ES6 is primarily motivated by being a target for concatenation tools, and so is not needed in TypeScript".
Can you elaborate on why it's not needed?

My impression is that it would be easier to know how to 'load' that resource both by the browser or by a compiler like TypeScript, examples here:

Or these here:

Either way, I'm starting to be utterly confused by the changes to the modules spec even if I've read the discussions,

What I use right now is:

/// <reference path="classes/misc/color.ts" />
/// <reference path="classes/html/dom.ts" />

So while I'm loving TypeScript, dealing with the modules system to organize my code is a PITA.

// Specific import declarations are nice:
import { events } from 'classes/html/dom';
import { Color } from 'classes/misc/color.ts';

// loading from a URL
module JSON from '';

That's about the only syntax I'm tempted to use.
There seems to be a strong desire to avoid namespaces and polluting the global scope at the cost of unnecessary complexity.

I do agree with "This part of the ES6 design is also the least proven so far."
Jun 21, 2013 at 8:04 AM
First of all, really like how the type system turned out. The 0.9 release with the generics added to it really makes it ready for everyday use in my opinion, great job.

But I was hoping we would also get such an "improvement iteration" that would fix the current module approach. So improve it before we would get a final 1.0 version. Right now I often get the feeling that the module system is more of a burden than a help. And because of that it doesn't really encourage or promote writing modular code.

What I would see as main areas for improvement:

1) Don't differentiate between internal and external modules at language level. Just use everywhere the external module syntax.

Make it a compiler/package option when people want to package multiple modules/files into a single file (like most languages do).
Also when you develop a module that could be reused by other developers, you don't have to make two versions of it. We might of course have to give up on the "open" nature of internal modules, but at least a price I'm willing to pay.

2) Allow directly to specify what to import, something along the lines of:
            import {sum, pi} from 'math';
This makes using modules much more elegant and not everywhere in your code you have to use prefixes (Math.pi) or define aliases (pi = Math.pi).

With these two items fixed, I would say much of the current issues I'm having with modules would be gone (not sure that is the case for others as well).
Jun 24, 2013 at 3:52 PM
I would have liked to get some more improvements into the module system before 0.9 went out the door, but we ultimately opted to keep things generally the same. I suspect we'll do shorthand like you suggest (which is, or at least was, part of the ES6 proposal) that allows you to import a few symbols from a module.

One thing we may support is a way to alias imports, like you suggest. Something like this:
import pi = Utils.Math.pi;
It didn't make it into 0.9.0, but may be in for 0.9.1.

As for not differentiating between internal and external modules - we're being conservative here because we'd like to have a design that works well with ES6 as ES6 matures instead of coming up with a design that may directly conflict. If they work together, we can just support additional syntax in the future that plays well with the existing TypeScript syntax.
May 27, 2014 at 1:34 AM
Any update on this after the typescript 1.0 ? If not, what alternatives do you have when you use typescript but don't want the coupling to the module system/build tools?
May 27, 2014 at 4:41 PM
We're still planning to align with the ES6 module system when it lands. The external module system in TypeScript is fairly decoupled from the rest of the language in that it's a pretty clear opt-in. For ES6 modules, we'd likely add it to the language without replacing the existing system. They fill different roles. The external modules that TypeScript currently supports target RequireJS and CommonJS, which isn't the focus of ES6 modules.