2

Using typescript, I am attempting to get 'modules' and 'imports' and such to work, and am having a bit of a rough time. I was asked to make an example of my problem, so here it is;

I use namespace style declaration to try and organize various parts of the project, this is just how I work the best and it helps me keep things free of a clutter that bothers me, so each typescript page starts with the namespace, and then it exports the corresponding class.

/app_content/scripts/admin/models/Item.ts

module website.admin.models {
   export class Item {
      // properties, etc
   }
}

/app_content/scripts/admin/ui/Component.ts

module website.admin.ui {
   export class Component {
      // properties, etc
   }
}

Then I will attempt to use one of these in a different file, as I have seen in many, many tutorials;

/app_content/scripts/admin/views/ItemView.ts

import component = module('website.admin.ui.Component');
import item = module('website.admin.models.Item');

module website.admin.views {
   export class ItemView {
       // try to use stuff, do other stuff, etc.
   }
}

However, I get the error Module cannot be aliased to a non-module type. I have yet to get any of these imports working at all - let alone how I want them. Is there anything that can be done?

I have tried this with Visual Studio set to use both CommonJS and AMD style and such, in the properties.

1 Answer 1

3

Drop Module Declarations

The first step is to remove all your module declarations...

module website.admin.models {

All of those can go because you are using External Modules, so a file === a module. The entire contents of the file is treated as if it were a module. External Modules never dirty the global namespace in any way, which is cool.

Importing

So without the module declarations, what is your module name? It is the path to the module, so now when you import, you do it like this:

import component = require('./app_content/scripts/admin/ui/Component');

Important note - don't add the file extension.

Important additional note - use require instead of module (this changed in the TypeScript specification).

Full Example

So your code now looks like this...

/app_content/scripts/admin/models/Item.ts

export class Item {
    // properties, etc
}

/app_content/scripts/admin/ui/Component.ts

export class Component {
    // properties, etc
}

/app_content/scripts/admin/views/ItemView.ts

import Component = require('./app_content/scripts/admin/ui/Component');
import Item = require('./app_content/scripts/admin/models/Item');

export class ItemView {
    example() {
        var component = new Component.Component();
    }
    // try to use stuff, do other stuff, etc.
}

Exporting Something Else

Additional cool feature alert! Once you have the above working, try this...

If you don't like this repetition...

var component = new Component.Component();

If you only have one class in Component.ts, you can export the class in place of the module like this...

class Component {
    // properties, etc
}

export = Component;

Now you can use the much prettier:

var component = new Component();

In your ItemView.ts file.

Runtime

To actually kick this all off in a web browser, you just include require.js and tell it your top level program file (usually app.ts, for example). It will load app.ts, then when it encounters a require it will load that module and so on.

<script data-main="/scripts/app" src="/scripts/require.js"></script>

Again, leave out the file extension in the data-main attribute.

Sign up to request clarification or add additional context in comments.

2 Comments

Is there a way to set up a 'base' url so that I can omit the ./app_content/scripts/ part? I seem to recall that requirejs had something like that.
I believe you can do it in the require.js config - but I'll be honest and say that it is actually easier to use the full paths in TypeScript - you only need them in the import statements. This is because the TypeScript language service won't know about the require.js config - so it will complain about the short path.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.