Search code examples
typescriptdurandal

declaring var results in undefined error


I'm a typescript newbie, I'm picking up an existing durandal project to make some changes. I've noticed that this code snippet gives a runtime error.

declare var routeLinks: IRouteLinks;
routeLinks = new RouteLinks();
export = routeLinks;

Error = Failed to load root module (ui/shell). Details: routeLinks is not defined(…)

When I change the code to remove the declare keyword (below) however, the issue goes away and the code seems to work as intended.

var routeLinks: IRouteLinks;
routeLinks = new RouteLinks();
export = routeLinks;

This pattern is replicated in a number of places, each time I get a runtime exception I go in and remove the declare keyword and it fixes the issue.

  • Can anyone explain why including the declare keyword is causing this issue, and why removing it fixes it?
  • What was the possible intention of using the declare in this context the first place (in newbie terms if possible)?
  • And if this code was previously working, how come on my box it fails? (breaking changes between typescript or durandal versions maybe?)

Thanks.

Further Info

Looking in to this further, when I compare the compiled js i see this line is missing when we use the declare keyword

 var routeLinks;

So the error now makes more sense to me, but why does using declare cause the cross-compiler to drop the variable declaration, this seems counter-intuitive.


Solution

  • The idea about behind the declare keyword is to tell the compiler that a variable (or class, function, etc) will be present at runtime when the code loads into the environment.
    This is helpful when using libraries that don't have declaration files for example.

    For example, the following code:

    declare var VERSION: string;
    console.log(`loaded version: ${VERSION}`);
    

    Compiles to:

    console.log("loaded version: " + VERSION);
    

    While this:

    var VERSION: string;
    console.log(`loaded version: ${VERSION}`);
    

    Compiles into:

    var VERSION;
    console.log("loaded version: " + VERSION);
    

    When the declare keyword is used then the compiler will just ignore it and won't output it to the generated js.

    In your case the variable is probably isn't defined at runtime, which is why you don't get an error when removing the declare.

    You can read more about it here: Quick Tip – TypeScript Declare Keyword