Home » Nodejs » TypeScript class per file in same namespace in Node.js

TypeScript class per file in same namespace in Node.js

Posted by: admin November 29, 2017 Leave a comment

Questions:

What is the pattern for one class per file where multiple classes (and therefore multiple files) contribute to the same namespace? I’m asking this specifically in a Node.js context.

I know how to define one class per file in the same namespace:

foo/A.ts:

module foo {
    export class A {
    }
}

foo/B.ts:

module foo {
    export class B {
    }
}

main.ts:

/// <reference path="./foo/A.ts"/>
/// <reference path="./foo/B.ts"/>

// TODO: How do I import the foo namespace at runtime?

TypeScript is supposedly a language for application-scale JavaScript development, yet we seem to be left out in the cold on the most fundamental aspect of application-scale development, which is how to layout and structure code files and how everything is linked together at runtime.

Answers:

In nodejs each file is a module. When you are writing code for nodejs using module (what typescript calls internal modules) is not required.

The foo is file A is actually A.foo and the foo in file B is actually B.foo. This is the way nodejs works. Typescript is following what is conventional in nodejs.

More info on external vs. iternal modules : http://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1

PS regarding:

most fundamental aspect of application-scale development

It is fundamental in the browser, not in nodejs. There is no global scope in nodejs the way there is in the browser.

Questions:
Answers:

As basarat mentions, in Node.js, files are modules. The correct way to write the code you are working on is:

foo/A.ts:

class A {
}

export = A;

foo/B.ts:

class B {
}

export = B;

main.ts:

import A = require('./foo/A');
import B = require('./foo/B');

This is detailed in the Imports and Exports section of The Definitive Guide to TypeScript.

Questions:
Answers:

This will work if all the TypeScript files are compiled to a single JavaScript file using the --out option. No further code is required. Without this option, main.js (from main.ts) will not see module foo and a ReferenceError will be thrown.

Thanks to Basarat for linking to one of his videos which recommends the --out option: http://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1

Questions:
Answers:

A bit late to the party, but I wrote a grunt plugin that lets you use the file-per-class/AMD style of programming in node and compile that code for both AMD (the browser) and CommonJS (node) while avoiding the use of client-side shims like requireJS.

https://www.npmjs.org/package/grunt-contrib-serverify-ts

It’s a bit rough and ready at this stage, but it’s working for me on a reasonably complex project.