By masonk


2014-06-30 17:58:54 8 Comments

In our pre-existing codebase, we use the "classes are Functions and Functions are Objects" aspect of JavaScript to do namespacing.

E.g., suppose we have a class named Foo, that contains a class named Bar.

Foo is a globally exported object, (i.e, it exists at window.Foo), and window.Foo.Bar is the constructor for Bar. (I think it's fair to say that this is a common JavaScript pattern).

It's true that this pattern creates a directional dependency. Foo must be loaded before Bar. We accomplish this using stealjs, an asynchronous module loader that is not conformant with AMD protocol. For this reason, we cannot use TypeScript's built-in import/export AMD code generation. At least, not until we do several weeks worth of drudgery to port our entire code base to requirejs.

To match this pattern in TypeScript, we speak of a class named Foo, and also a module named Foo.

class Foo {
    /* Foo's properties */
}

module Foo {
    export class Bar {
    /* Bar's properties */
    }
}

This is legal TypeScript and it compiles to the JavaScript situation described above: the Foo class object will contain the Bar class object as its "Bar" property. The Foo module is said to merge with the Foo class, and Bar is said to be an inner class.

However, if I simply separate these two statements into separate files:

// Foo.ts
class Foo {
    /* Foo's properties */
}

// Foo/Bar.ts
module Foo {
    export class Bar {
    /* Bar's properties */
    }
}

This is no longer legal TypeScript, and it doesn't compile. [1] (This despite the fact that we could and would arrange for the second file to be loaded after the first file loads via our own module loader.)

This is a big problem for us, because we're not about to smoosh all of our inner class declarations into one file. As far as I can tell, there is actually no solution to this. We simply have to pollute the global namespace and cannot merge inner classes with our namespaces.

If we were using TS's built in import/export semantics this problem wouldn't come up, but we aren't, for the reason described above. Porting everything to requirejs is not on the table right now. Given our situation, what do you think is the best strategy for working around the class-module merging restriction?

[1]TypeScript: Module x cannot merge with previous declaration of x in a different file

1 comments

@WorldMaker 2014-11-05 16:19:05

You can switch to require.js AMD piece at a time rather than rewrite everything all at once. The easiest way to do that, in fact, is to rely on TypeScript's built-in AMD support, since it automates so much that you need to do and the export and import syntax in TypeScript is very easy to work with. Files that you don't add export or import statements to them in TypeScript get built as they currently are and files that use export/import become AMD modules. There is a bit of a learning curve to this as you will need to add a require config and start to use the require(['mytsamd'], function (mytsamd) { /* do stuff with mytsamd */ }) pattern (or convert that to a promise with something like Q.js) in non-TypeScript files that need to refer to AMD objects.

Related Questions

Sponsored Content

1 Answered Questions

[SOLVED] Typescript module was successfully resolved but cannot be found

  • 2019-01-04 18:26:14
  • Jesuspc
  • 130 View
  • 1 Score
  • 1 Answer
  • Tags:   typescript

2 Answered Questions

[SOLVED] Is this a valid typescript declaration file?

  • 2019-02-07 07:04:55
  • Abhi
  • 55 View
  • 1 Score
  • 2 Answer
  • Tags:   typescript

1 Answered Questions

[SOLVED] TypeScript definition for RequireJS Module return without export

1 Answered Questions

How to map TypeScript ES6 default imports to return values of AMD modules?

1 Answered Questions

[SOLVED] Export a Global and Define via TypeScript Module System?

1 Answered Questions

1 Answered Questions

Importing AMD modules that don’t use exports with TypeScript

1 Answered Questions

2 Answered Questions

1 Answered Questions

[SOLVED] Reference module exported using “export =” in TypeScript

  • 2013-09-01 10:41:05
  • sroes
  • 2975 View
  • 3 Score
  • 1 Answer
  • Tags:   typescript amd

Sponsored Content