node.d.ts question?

Topics: General
Mar 3, 2014 at 2:40 PM
Edited Mar 3, 2014 at 3:42 PM
Hi,
I have run in situation when I would like to assign type »path« to some variable in node project. Normally when you import »path« you would do something like this:
import path = require('path');
but as path is defined in node.d.ts following statements is not possible (this is what I would like to achieve):
var path:typeof Path = require('path');
Current definition in node.d.ts is:
declare module "path" {
    export function normalize(p: string): string;
    ....
}
Maybe it will be more general that it will be defined as:
declare module Path {
    export function normalize(p: string): string;
    ...
}


declare module "path" {
    export = Path; 
}
I have just given example for path module, but it is the same for all others. Maybe I’m missing something and this is also possible with current node.d.ts definition?

Any thought...
Developer
Mar 3, 2014 at 8:40 PM
You can check out the samples we ship which include a simple use of node.d.ts (https://typescript.codeplex.com/sourcecontrol/latest#samples/node/HttpServer.ts). In short, what you need to do when referencing these sorts of .d.ts (ones with quoted module names in them) is use a /// reference to the .d.ts to pull in the quoted module names which you can then import/require. This is one of the only times you want to mix /// and import/require in the same file. You also should not need to use a type annotation on the import statement when this is working correctly.
Mar 4, 2014 at 9:05 AM
Thanks for response, but I think that you haven't understand me correctly. The problem is that I can't use import statements. I'm trying to split single node project (150+ ts files) to multiple node projects. Each project will produce only single js file. The only way to do this is to change module system from CommonJs to None and then after compiling each library, add exports statements in generated js file with some post-build task. I have tested on simple project and it runs perfect. Because I add exports statements at the end of js file even source maps remains unattached. The problem is, that it is not possible to compile ts file with import statements when module system is set to none. (You get: Build: Cannot compile external modules unless the '--module' flag is provided.) So this is the reason why I would like to change:
import path = require('path');
to
var path:typeof Path = require('path');
The other thing is dynamic require with type annotation. Following is not possible:
if (true) {
    import path = require("path");
    console.log(path.sep);
}
This works but without type info:
if (true) {
    var path = require("path");
    console.log(path.sep);
}
And you are not able to add type annotation as node.d.ts is defined.

Most other public d.ts files are declared so that can be used this way. They declare module with all exported staff and then they export this module with export = Module, but this is not true for node.d.ts.
Mar 4, 2014 at 4:57 PM
@EdvinV, regarding your second issue "dynamic require" or lazy loading, I believe the following will work
import pathTypes = require('path');

class Foo {

  doFoo(){
        
     var path: typeof pathTypes = require('path');
     path. // intellisense
   }
}
Since the import is being used only for type annotation it gets optimised away.
Mar 6, 2014 at 9:26 AM
@nabog, thanks for info, now I remember that this is also described in documentation. But this means that following code should be compiled without CommonJs module options.
/// <reference path="node.d.ts" />
import pathTypes = require('path');
var path: typeof pathTypes = require('path');
but it is not and compiler gives »Cannot compile external modules unless the '--module' flag is provided.«. In documentation it is stated that modules are external if there is top level export or import directive, but IMO if import directive is only used for type annotation this is not external module and compilation should pass. So is this bug or default behavior?

thanks again