modules and scoping

Topics: General
Oct 4, 2012 at 10:44 AM

Suppose I have two different classes in two files (parent.ts and child.ts):

/// <reference path='child.ts'/>
class Parent {
    children:Child[];
}

/// <reference path='parent.ts'/>
class Child {
    parent: Parent;
}


To compile I use the following command: tsc parent.ts
This works all as expected with the great benefit of some type checking. However as soon as in any of the two files I add any import or export statement, it doesn't compile anymore. It cannot resolve the classes in the other file anymore.

I guess this is due to the fact that the file changes into a module as soon as you add import or export statements. Is this the intended behavior and is there any way (without major re-factoring) to make it then compile again?

regards,

Peter

Oct 4, 2012 at 1:32 PM

When using the TypeScript flavor of modules, imports are not used, because you define the required sources as references i.e.:

/// <reference path="another_file.ts" />


The result of compilation is javascript with self invoking function module pattern. In this case there is no module defined really, just an object as a result of self invoking function. In browser environment you should know the order of loading for this pattern to work properly and you do not need any additional information to use it.

When using commonJS/AMD modules you need to use import statements because those are part of the loading work done by the environment (either node or requirejs/similar). import statement will be transformed to 'require' statements. 

One can think of it as 'the old way' of doing modules in js: you order the scripts manually and you make sure objects used in moduleB and defined in moduleA have been loaded after moduleA. The 'new way' is providing information about the dependencies in the module itself and use module loader that can understand and use this information to load your modules in the correct order. 

For more details one can take a look at the demo applications, as various techniques for building are used there, demonstrating the various module patterns supported by the compiler. 

Oct 4, 2012 at 10:04 PM

Thanks for the feedback, much appreciated!!!

The example I gave is actually based on how part of the tsc compiler is coded (in the services directory), or at least my understanding of it. The nice thing is that you can refer to classes etc without having to use prefixes. If I would have used an import statement like the following:

import xyz = module("child");

my declarations would have to look something like this:

children: xyz.Child[];

Just doesn't look as nice. Wat would be great if you could import directly into the "current scope". So for example: 

import module("child"); // No xyz this time.

P.S I also found out that if I wrap my original code into a module it works as I hoped for. They actually did that in the tsc source code, but I assumed (wrongly so) that if you don't specify a module, it would all be part of a kind of "ROOT" module and behave similar.