1

Say you've got a ViewModel (or other RequireJS module) that looks like this:

define(['plugins/dialog'], function (dialog: /* what type should go here? */) {

/* rest of module */

}

For reference, the type we are interested is the Dialog interface, which is defined like this in durandal.d.ts:

declare module 'plugins/dialog' {
    interface Dialog {
        owner: any;
        context: DialogContext;
        activator: DurandalActivator<any>;
        close(): JQueryPromise<any>;
        settings: composition.CompositionContext;
    }
}

This type of module definition is referred to as an "ambient external module declaration." As @basarat noted here, you need to use import in order to gain access to these modules. Here's how your ViewModel needs to be updated:

import dialogModule = require('plugins/dialog');
define(['plugins/dialog'], function (dialog: dialogModule.Dialog) {

/* rest of module */

}

This works at compile time, but the generated JavaScript now looks like this:

define(["require", "exports"], function(require, exports) {
    define([

    /* rest of module */

    });
});

You can see that the module was wrapped in an extra "define()" call. This results in a mismatched anonymous define error when you try to show the dialog (i.e., when Durandal tries to retrieve this module).

So, is it possible to "import" and make use of types inside ambient external module declarations, without it wrapping your file in an extra define()?

Community
  • 1
  • 1
Josh
  • 7,232
  • 8
  • 48
  • 75

1 Answers1

1

Ideally, the Durandal .d.ts would be written differently (such that you could access the interface without importing the module).

As a practical solution, you could compile your file with --module commonjs instead of --module amd. The require call will be optimized away and you'll still get type information.

You could also compile with --module amd and rewrite your code to not explicitly call define (just let the compiler generate that, like it's trying to), though I'm assuming you've avoided doing that for intentional reasons.

Ryan Cavanaugh
  • 209,514
  • 56
  • 272
  • 235
  • 1
    Switching to CommmonJS fixed it for me. I'm not entirely sure of all the implications, since I'm extensively using RequireJS (AMD) throughout the rest of the project. Could you expand on that a bit? This is a large, existing project that is being slowly migrated to TypeScript. We're just renaming the files to .ts and adding type information as we're continuing development. This allows us to slowly "sprinkle in" type information, and allows the TypeScript compiler to catch more and more issues. – Josh Jun 13 '14 at 18:18