How to allow for "!" in module import name?

Topics: General
Jan 6, 2013 at 7:52 PM

How can I make this work?:

import test: string = module("dojo/text!./templates/SomeWidget.html");
Coordinator
Jan 7, 2013 at 7:55 PM

We don't currently support importing html pages as modules.  What are you trying to do?

Jan 8, 2013 at 6:31 AM
Edited Jan 8, 2013 at 6:34 AM

A lot of libraries such as Dojo or Requirejs alow you to import any type of file (such as language files etc.) using AMD "Loader Plugins". 

See https://github.com/amdjs/amdjs-api/wiki/Loader-Plugins

I have also found that this question is related to:

http://typescript.codeplex.com/workitem/388

I believe that something like:

import text = module("Any text that I want! :o) ") as String;

would be general enough to work with any loader plugin.

Jan 8, 2013 at 7:40 PM

Sounds like literal programming!

Dec 8, 2013 at 8:46 PM
Edited Dec 8, 2013 at 9:47 PM
Importing resources in this way is essential to a significant amount of AMD code. Not being able to use loader plugins makes adoption of TypeScript extremely difficult for AMD users.

Currently, the following works as the only workaround as of TypeScript 0.9.5:
  1. Manually declare an ambient require global in e.g. require.d.ts: declare var require:{ (moduleId:string):any; };
  2. Add a /// <reference path="require.d.ts" /> in the module that uses the loader plugin.
  3. Use the undocumented /// <amd-dependency path="moduleId" /> comment to make the compiler add the module ID as an AMD dependency when it writes out the module.
  4. Use var foo:type = require('moduleId'); to “import” the module.
This is a very confusing and inelegant solution. Surely TypeScript can have something better?
Coordinator
Dec 9, 2013 at 7:00 PM
The gist of the current design is that there are two ways to import a module:
  1. Use 'import x = require("y")' syntax
  2. Use 'declare var require; var x = require("y")' syntax
In the first case, the compiler will track through the path you give, because the job of "import" is to additionally handle any types that come from this import. In the second case, all we care about is loading the module. There's no checking by the compiler that the path you give it is correct. You're also opting out of any compiler help for creating the module load code.

tl;dr - the first one has more requirements but the compiler gives you more help. The second one is all manual.

With that, it makes sense why you would need to manually do the steps that the compiler is doing for you if you choose the manual case. You need to choose this case when you're using a style of import we don't support by default, like the "!" imports or importing .html pages. In those cases, you need to tell the compiler what's required (using amd-dependency, eg) and also handle setting up the type.

I agree it's on the "serviceable but not pretty" side of things once you get outside of the more automatically support scenarios.