Reputation: 5925
I have a node.js application. As all non-trivial applications, it's split across many files. For simplicity's sake let's say there are two files:
Base.ts
module MyNamespace {
export class Base {}
}
Derived.ts
/// <reference path="Base.ts" />
module MyNamespace {
export class Derived extends Base {}
}
In TypeScript's terminology they're internal modules. Now, I want to use a node.js module inside of the file Derived.ts
. The naïve approach would be to just import it.
/// <reference path="Base.ts" />
/// <reference path="node.d.ts" />
import fs = require('fs');
module MyNamespace {
export class Derived extends Base {
stats: fs.Stats;
}
}
However, if we try to compile this code, we'll receive an error 2304 Cannot find name 'Base'
. This is happening because a module containing a top level import
or export
is an external module, and external modules can't be spread across files; in other words, they're sealed, as it's called in Scala, C#, and, perhaps, somewhere else. It, in turn, means that the file Base.ts
doesn't contribute to MyNamespace
anymore. Even though I believe it's a perfectly reasonable desire to have a common namespace and to be able to depend on other - external - modules.
I've tried some workarounds, but none of them was perfect.
Use var
instead of import
. No top level import means the module does not become external. However, if we import a module with var
we aren't able to use it in type positions, only in value ones.
Make all the modules external. Basically, we'd remove the namespace and instead of referencing the other modules in the files that depend on them use the import
statement. Like good old #include
. Besides having to do a ton of requires it means that every module compiles to a separate file, and now to load the application we need to read a lot of files instead of one.
Keep everything in one file. Solves the problem with the sealness (is there such a word?) of external modules. This one is good for small programs, but having a file that's bigger than even 1000 lines of code becomes unmanageable.
Create a wrapper. If you have only a few modules to import, and they're rather small, you can import them with var
, and create wrappers that delegate the functionality. Obviously, not the cleanest solution and becomes cumbersome as the number of modules grow.
So, my question is how to properly import a node.js module into a file containing an internal TypeScript module that is spread across multiple files. Also, I'd like to understand why it isn't possible to go with my first naïve approach.
Upvotes: 2
Views: 1499
Reputation: 250922
My personal recommendation is your option 2.
Make all the modules external
This is how node is set up to run, so don't fight it. Yes, it will load files from the local disk when you are running your application, but it is also set up to optimize subsequent requests for the same resources.
Each file represents a module, so you don't need to use the module
keyword in your application (and you don't need any reference
comments - just the import
statements). You can create a hierarchy if you wish using a folder structure, although I prefer tall, rather than deep, structures.
Upvotes: 1