52
Vote

Allow module.exports

description

As discussed here (http://stackoverflow.com/questions/12696236/module-exports-in-typescript), it would be a very handy feature if exports like the following:
export class Greeter {}
compiles to:
module.exports = Greeter; or exports = Greeter;

comments

jonturner wrote Oct 4, 2012 at 3:07 AM

Thanks for the suggestion.

delaaxe wrote Oct 4, 2012 at 1:24 PM

I'm using this pattern in all my codebase, and I think I'm not the only one. I'd really like to see this possible.
Maybe allow syntax like

exports = class Greeter {}

once class expressions will be supported.

KerstenB wrote Oct 4, 2012 at 1:48 PM

Yes, that was my attempted too. Most of the libraries I am using are working like this and not the way as it is now.

damassi wrote Oct 5, 2012 at 6:28 PM

Just ran into this yesterday. All of my files use this pattern and currently it breaks in TypeScript / not backwards compatible.

rwaldron wrote Oct 6, 2012 at 11:02 PM

I think module could be declared in a .d.ts file, with an exports property... Haven't tried it, but worth a shot

rwaldron wrote Oct 6, 2012 at 11:06 PM

I should have noted that this is absolutely possible because module{} syntax is contextual with a look ahead for the curlies

rwaldron wrote Oct 6, 2012 at 11:19 PM

dcstraw wrote Oct 18, 2012 at 5:44 PM

I agree that this is an important feature. I have existing JavaScript code that exposes exports that are meant to be used like a base class, i.e. you call {exportname}.apply(this, ...). Currently I can't use TypeScript's class concept to interop with this code but classes would be perfect for this.

rwaldron wrote Oct 18, 2012 at 6:38 PM

@dcstraw To take full advantage of TypeScript, you should probably re-factor those to be actual modules with class definitions that are inherited with "extends" and use "super()" instead of "the old fashioned way"

dcstraw wrote Oct 18, 2012 at 8:04 PM

@rwaldron agreed but in this case I don't control the code I'm calling, and it's probably not going to be converted to TypeScript any time soon. I'm treating that code much like any other JavaScript library, and I'm providing .d.ts files to add typing information.

dallonf wrote Nov 9, 2012 at 6:59 PM

This is seriously blocking backwards compatibility for my team (deployd.com). We'd love to write a TypeScript definition file for extensions, but we use module.exports all over the code base and it's impossible to write the subclasses our API depends on with wrapping them in a JavaScript file that uses the "exports" pattern instead.

damassi wrote Nov 12, 2012 at 12:21 AM

Perhaps this should be elevated a bit higher than 'impact: low' because this is a WIDELY used design pattern that completely breaks old code.

rwaldron wrote Nov 12, 2012 at 3:19 AM

I imagine this could happen, but only as an optional tsc compile flag. Anything else is breaking the line between language and library.

LukeH wrote Nov 29, 2012 at 12:05 AM

See also http://typescript.codeplex.com/discussions/404795 on the discussion page.

EisenbergEffect wrote Jan 3 at 2:43 AM

This is a serious blocking issue. It is an extremely common practice to export a constructor function as a module's export. The original ES6 module spec didn't allow this, but they have made some improvements and now it does...along with a few other changes. TypeScript should be synced up with the improved module spec as soon as possible to enable compatibility with ES6 and enable this key scenario.

LukeH wrote Jan 3 at 10:48 PM

@EisenbergEffect - definitely understood that this limits some significant module usage patterns. The ES6 syntax and semantics for this feature are still in some flux, and we are working with the TC39 group on getting this part of the ES6 proposal stabilized as soon as possible. As soon as this looks stable, we fully expect to add "export =" style syntax as in ES6.

EisenbergEffect wrote Jan 21 at 7:25 PM

Thanks for the update Luke!

TimSpeed wrote Mar 1 at 3:50 PM

  • Bump :P
    This is essential to develop nicely structured code in node
    Change things around so that only one export is allowed at the global level.
    This can be either a class or module
    Exporting a module would give the same effect we have now
export module "server" {
    export class ResponseHandler ...
    export class Server ...
}
And to make things even nicer it should accept referencing of files with the same exported module
Then everything would merge, similar to the internal module design pattern, except one could actually import things in referenced files.
for example Server.ts:
/// <reference path="./Net.Server.ts" />
/// <reference path="./Net.ResponseHandler.ts" />
export module "Net" {
    export var CONNECTION_TIMEOUT = 20000;
}
Net.Server.ts
/// <reference path="./node.d.ts" />
/// <reference path="./Net.ResponseHandler.ts" />
import http = module('http');

export module "Net" {
    export class Server ...
}
... Oh if only :)

LukeH wrote Mar 10 at 1:57 AM

@TimSpeed - Indeed, we are working on a syntax for enabling this in the current 0.9 branch. The specification draft in the "doc" folder there now includes an "export =" declaration (section 9.2.1) that would provide basic support for modules representing single value exports. More work in spec drafts and implementation on the way soon.

blittle wrote Mar 25 at 8:07 PM

Definite +1 on implementing this. Generally it is best practice for a module to do one thing and one thing only, which in many cases translates to exporting only one item. If only one is exported, why not have that directly be the exports object? Then the whole file can be named the exports module, example:

Telescope.ts
export class Telescope {}
Observatoroy.ts
import Telescope = module('Telescope');
var telescope = new Telescope.Telescope();
Wouldn't something like this look nicer?

Telescope.ts
exports = class Telescope {}
Observatoroy.ts
import Telescope = module('Telescope');
var telescope = new Telescope();

PulsarBlow wrote Apr 13 at 1:06 AM

+1, this is really much needed.

Scriby wrote Apr 17 at 4:11 AM

+1, ran into this last night when trying to convert a project over to using TypeScript

jonturner wrote Apr 26 at 9:52 PM

We're looking into this for 0.9.

The gist for the feature is that you will be able to "export = symbolName" and that would export the namespace/type/value information for that symbol name.
//fileA.ts
class Telescope { ... }
export = Telescope;

//fileB.ts
import Tele = require("fileA.ts");
var tele = new Tele();

anurse wrote May 16 at 6:37 PM

@jonturner - Is this in the 0.9 preview? I'm trying to use it and getting "tsc.js(689, 13) Microsoft JScript runtime error: please implement in derived class" from the compiler. If it's not there, that's OK, but I'd like to add another vote for making sure it makes it in to 0.9 :)