title: How to properly use modules and interfaces in TypeScript with NodeJS target?
body: <p>My team and I are new to TypeScript and NodeJS, and we're having some serious troubles getting this project off the ground. It's meant to be a modularized game asset pipeline written in TypeScript for use with NodeJS (I wasn't involved in the decision making here, and the discussion is still sort-of-ongoing, but we still need a prototype).</p>
  
  <p>We have a good idea of the architecture already, but it's kinda difficult to even get the prototype running, because I just can't seem to manage to wrap my head around how modules work in combination with interfaces and external dependencies. Some of our components also need to use NodeJS or other library modules (e.g. NodeJS.fs for reading/writing files), and we'd prefer to be able to use <code>///reference</code> to add the appropriate d.ts files to keep type safety at development time.</p>
  
  <p>An example of the supposed project structure is:</p>
  
  <pre><code>/pipeline
      /log
          - ILog.d.ts
          - StdOutLog.ts
          - FileLog.ts
          - ...
      /reader
          - IReader.d.ts
          - TextReader.ts
          - ...
      /parser
          - IParser.d.ts
          - XmlParser.ts
          - JsonParser.ts
          - ...
      /task
          - ITask.d.ts
          - JsTask.ts
          - CliTask.ts
          - ...
      /...
  </code></pre>
  
  <p>The way we want to use it is that we provide default implementations for our interfaces (to cover the basics, e.g. running a console command, logging to a file or a stream, reading JSON and XML configs, ...), as well as the interfaces themselves so that other teams can create their own extensions (e.g. <code>class GitTask extends CliTask</code> to encapsulate repository operations, or <code>class JpgReader implements IReader</code>).</p>
  
  <p>On the calling side, in a different project/runner app, it should work like this:</p>
  
  <pre><code>import pipeline = require('pipeline');
  
  //...
  
  var log = new pipeline.log.FileLog();
  log.info("filelog started");
  
  var parser = new pipeline.parser.XmlParser();
  parser.parse(somexmldata);
  log.info("parsing XML");
  
  // ...
  </code></pre>
  
  <p>I'm very likely just doing it wrong (tm), but I feel that it's not easily possible to do with TypeScript what we want to do, especially considering that e.g. the definition for the log component can easily have several interfaces and also enums (factory, logger, logitem, logtarget, loglevel). As far as I understand, NodeJS modules need to be a single JS file, but using even a single <code>import</code> turns your module into an external module and those won't compile into a single file anymore, so that seems like a pretty steep roadblock to me.</p>
  
  <p>Is there a way to realize that strucute and intended usage with TypeScript targeting NodeJS? If yes, what would the files need to look like (especially regarding the module hierarchy and component FQNs, e.g. pipeline.log.X, pipeline.task.Y, etc; how would I properly use <code>module</code> and <code>export</code> for it)? If no, what are suitable alternatives to achieve our goal?</p>
  
  <hr>
  
  <p><strong>[Update]</strong> I've refactored my prototype according to basarat's suggestion, and it already looks much better than before. However, I've encountered a compile error when using one class from another:</p>
  
  <pre><code>error TS2095: Could not find symbol 'LogItem'.
  </code></pre>
  
  <p><code>LogItem</code> is a class defined in <code>/log</code> and it's used by <code>StdOutLog.ts</code> in the same folder. IntelliJ gives me multiple definitions for it (obviously, one the <code>LogItem</code> class itself, and the other in <code>/log</code>'s index file where it's exported). I've tried using the module notation <code>log.LogItem</code>, but that didn't work. Adding all default implementation files to the global declarations file didn't work either. <strong>[/Update]</strong></p>
  
  <p><strong>[Update2]</strong> Here's some more code around where the error happens. I don't get any errors/markings in IntelliJ, only when running the grunt-ts task.</p>
  
  <p><em>// src/log/LogItem.ts:</em></p>
  
  <pre><code>///&lt;reference path='../pipeline.d.ts'/&gt;
  class LogItem implements ILogItem {
      // ...
  
      constructor(level:LogLevel, message:string) {
          // ...
      }
  
      public static create(level:LogLevel, message:string):ILogItem {
          return new LogItem(level, message);
      }
  
      // ...
  }
  
  export = LogItem;
  </code></pre>
  
  <p><em>// src/log/Log.ts:</em></p>
  
  <pre><code>///&lt;reference path='../pipeline.d.ts'/&gt;
  class Log implements ILog {
      // ...
  
      private getLogItem(level:LogLevel, message:string):ILogItem {
          return LogItem.create(level, message); // &lt;-- that's where I get the "symbol not found" error
      }
  
      // ...
  }
  
  export = Log;
  </code></pre>
  
  <p><em>// src/pipeline.d.ts:</em></p>
  
  <pre><code>///&lt;reference path="../typings/node/node.d.ts" /&gt;
  
  //grunt-start
  /// &lt;reference path="pipeline.ts" /&gt;
  /// &lt;reference path="log/Log.ts" /&gt;
  /// &lt;reference path="log/LogFactory.ts" /&gt;
  /// &lt;reference path="log/LogItem.ts" /&gt;
  /// &lt;reference path="log/StdLogEmitter.ts" /&gt;
  /// &lt;reference path="log/log.d.ts" /&gt;
  /// &lt;reference path="log/log.ts" /&gt;
  /// &lt;reference path="parser/JsonParser.ts" /&gt;
  /// &lt;reference path="parser/parser.d.ts" /&gt;
  /// &lt;reference path="parser/parser.ts" /&gt;
  //grunt-end
  </code></pre>
  
  <p><strong>[/Update2]</strong></p>