TypeScript module import in nodejs

What is best practice for importing modules in nodejs with typescript? I come from c# background so I want to do something like this

MyClass.ts

module MyNamespace {
    export class MyClass {
    }
}

app.ts

// something like using MyNamespace
new MyNamespace.MyClass();

or

MyClass.ts

export class MyClass {
}

app.ts

import MyClass = module("MyClass")
new MyClass();

I know I can do this and it will work, but then I have to think up for two names for each class

import MyClass2 = module("MyClass")
new MyClass2.MyClass();

Point is separating classes to multiple .ts files (preferably one file per class). So question is, how is this done?

Answers


You have two choices here:

If you insist on using CommonJS or AMD modules, then you will have to use external modules just the way you described it in your question. Whether or not you use a module to declare your own namespace is mostly a matter of taste. The only way to circumvent the issue of specifying two names is to create a variable that aliases the type:

mymodule.ts

export module MyNamespace {
    export class MyClass {
    }
}

app.ts

import ns = require('mymodule');
var myclass = new ns.MyNamespace.MyClass();
var myclassalias = ns.MyNamespace.MyClass;
var myclass2 = new myclassalias();

Your other option is to use internal modules which are mostly used to structure your code internally. Internal modules are brought into scope at compile time using reference paths.

mymodule.ts

module MyNamespace {
    export class MyClass {
    }
}

app.ts

///<reference path='mymodule.ts'/>
var myclass = new MyNamespace.MyClass();

I think you'll have to decide for yourself which of those two approaches is more appropriate.


You can import TypeScript modules into a node.js file using the typescript-require module, which was created for this specific purpose.


I would recommend against using the explicit module (or namespace) keyword, it's a vestigial remnant of an earlier time.* You generally don't need them because any typescript file with a top-level import or export is automatically a module. Your second myModule.ts example was good.

export class MyClass {
   ...
}

But when you import it to another typescript module, you'll want to use something like this:

import { MyClass } from './myModule';
var myInstance = new MyClass();

Personally, I don't like repetitiveness of line 1, but it is what the language calls for, so I've learned to accept it. I think the utility of this syntax isn't apparent unless you abandon the file-per-class pattern. You pick and choose what names to import from the module, so that no unintended namespace pollution occurs.

An alternative import syntax pulls in all names from the module, but you must qualify the names with the module when you use them. Therefore it is also name collision resistant.

import * as myModule from './myModule';
var myInstance = new myModule.MyClass();

There are exceptions to the general rule about not needing module / namespace keywords, but don't start by focusing on them. Think file == module.


Need Your Help

Complex angular js ng-class

angularjs ng-class

I have the component and have a problem setting the css class to it.

Haskell indentation doesn't line up function arguments

haskell emacs indentation

I'm using Emacs as my main Haskell editor, and as such, I of course use haskell-mode as the main mode for editing Haskell code.