4

I am having trouble declaring circular dependencies in Typescript. Here,s the code:

//Widget.module.ts

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

export module Widget {

    class Widget {

    }
}

//Buttons.ts

/// <reference path="Widget.module.ts" />

class Button extends Widget{
   function x(){
     ...
   }

   ...

}

In this, arrangement I want to have a main file defining a module and then a number of files referenced to, from that main file. These files could contain a number of classes that call, instantiate or inherit from each other.

Currently I am getting this error on the line containing "extends Widget" in the source Buttons.ts - whether I not its contained inside an exported module.

Could not file symbol widget

--Update--

The reason I want to use reference tags instead of import/require is that I want to compile these separate Typescript files into a single javascript file using the --out flag in the typescript compiler.

1 Answer 1

1

I'm assuming your two files are in the same folder?

From the current code, I can't understand why you'd want to reference Button.ts in the Widget.module.ts file, but that's not the point.

You are not including the Widget.module file, you are only referencing it. Referencing TypeScript files can only be used for type declarations, not implementations.

Change your code to:

import Widget = require("Widget.module");

class Button extends Widget.Widget {
   x() {
     // ...
   }

   // ...
}

Note that you need to reference the class as Widget.Widget as you are exporting the module, not the class. Also, in case you are building a web application you'll need a module loader to load in the widget module. In that case, take a look at RequireJS.


Update: The benefit of the reference tags is that you are able to reference types without having to import them. This can be useful

  1. in case you want to use an existing JavaScript library in your TypeScript code
  2. or for your own code.

In the latter case, assume for example you have other code that expects a variable to be of the type Button but you do not actually require the class itself.

class MyClassThatReferencesButtonButDoesNotActuallyNeedsTheImplementation {
    myMethodThatExpectsAButton(someVar:Button) {
        someVar.text = "My button!";
    }
}

The class does not need the implementation of Button, it just needs to know what properties and methods are available on it. The advantage becomes more clear when you understand that in case Button was imported rather than referenced, it needs to be loaded by a JavaScript module loader.

In the first case, let's say your Button class requires jQuery. Are you going to include jQuery together with your class? Or are you going to assume this is globally available? In essence, this is the same case as the one above: you don't need a TypeScript implementation of jQuery, you just need to know what properties and methods are available, hence you'll just reference a definition file for jQuery.

The --out flag is only useful to include referenced files. In case you have imported modules, you'll need to compile all files and then use the RequireJS optimizer to build your output to a single file.

5
  • 1
    Thanks for the answer. I want to use the reference tag for a reason. please read by updted question above. By the way, assuming you know better, can you please elaborate on what is the benefit of having reference tags in Typescript, given that in most cases we have to use import/require statements anyways? Commented Jan 13, 2014 at 10:19
  • To include referenced files is exactly what I want - how can I get that - given that fact that the super class is defined inside an exported module but the subclass is not - because its in a different file. In fact, I just tried putting the subclass "Button" inside a module of the same name assuming the Typescript compiler would merge the two upon inclusion. That didn't work either. Any thoughts in that direction? I really appreciate your help. Commented Jan 13, 2014 at 13:28
  • No, as you have seen for yourself, simply putting them in a module with the same name won't help. What you'll need to do is compile both files to AMD modules (this is the module format RequireJS can understand) and then either load in the files using RequireJS or let the RequireJS optimizer build all files to a single output. You can specify the module type by passing in --module AMD to your compiler
    – thomaux
    Commented Jan 13, 2014 at 13:33
  • I added the amd module flag to the compiler, but Webstorm is still throwing the error in the editor - although the compilation seems to be working fine. Thanks for helping out. Commented Jan 13, 2014 at 14:20
  • Yeah, I have issues with WebStorm as well, sometimes he has hiccups. Have you updated to the latest version (I believe it is 7.0.3). Glad to have helped!
    – thomaux
    Commented Jan 13, 2014 at 14:32

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.