Tuesday 31 December 2013

Typescript 0.9.5, Chutzpah and Visual Studio update woes

Introduction


This post is kind of a story. The story of how a simple (seemingly) update to Chutzpah version 3.0 and by extension Typescript 0.9.5 made an otherwise normal development day into a war against a legion of Typescript errors, most of which weren't even in our code.


If you're here, there's a chance you've come up against a similar issue. Hopefully this post can talk you through to a happy solution.



I can't take credit for remedying this problem, most of the work was done by one of my colleagues @RobinChesterman.


The project setup


The general file structure was something like this:


  • MainProj Main ASP.NET project
  • MainProj.Tests Tests project for server side unit tests
  • MainProj.Jasmine.Tests Jasmine tests project for Jasmine type tests

The main project does not have any _references.js or .ts file and does not use reference tags in the JavaScript. The Jasmine project has a _references.ts file, which has references to all the Typings d.ts files, the Lib .js files and the actual code of our project. This _references.ts file was then being referenced by our actual test files. This seemed a lot easier than copy+pasting the 80+ references, which we would have had to do otherwise.


It is entirely possible this whole situation may have been mitigated by having our Jasmine tests inside the main project, since Typescript in Visual Studio auto-detects other .ts files. Though true, having them separated out feels better from an architectural perspective. That and there's no chance of accidentally getting our tests appearing as loaded sources on the site. The reason for the wiring was the Typescript doesn't detect .ts files across projects, only within them.


When it all went wrong


Installing an update to your test runner on the morning of Friday the 13th was probably never the greatest of ideas. Regardless, that's what I did. Chutzpah 3.0 had arrived, bringing with it Typescript 0.9.5.


I went ahead and installed the updated Chutzpah extensions to Visual Studio, knowing we'd probably want to move to Typescript 0.9.5 at some point. I tried to run the Javascript tests, to see how things were coping. Errors all around. I wasn't overly surprised.


I also went ahead and installed the Typescript update. I then realised it didn't replace the already existing Typescript on my machine, so I then had 2 versions of Typescript (not good). So I uninstalled them both, then reinstalled Typescript 0.9.5.


With the updates installed and ready to go on my machine, I reopened Visual Studio. All seemed fine.


...That was, until Typescript had a look at my project and manage to count how many errors it thought there were. It was somewhere in the range of 500 or so! That might not seem that much to some people, but it did to me. I knew there would be breaking changes between Typescript 0.9.1.1 and 0.9.5, but it looked suspiciously high to me.


Finding the solution(s)


Those definitely typed files could use an update

At a closer look, most of the errors were in our discovery Typescript files (d.ts). With the new version of Typescript, some of our Typescript typings files were probably going to fall foul of the breaking changes introduced. Luckily for us, the borisyankov/DefinitelyTyped project was on the case and the Typescript typings we were using already had updates. So it was simple to go to our Library package manager and update the various typings we had installed.


Repeated files

In our main project, under Scripts/Typings, we had some of the typings living in their own folders and some living in the main Typings folder. Some of these were duplicated, so we removed the duplicates (the ones in the folders). For some reason, this was never a problem for the Typescript compiler before. It certainly was now!


Some genuine Typescript errors in our code

Our code wasn't blameless either, and we had some adjustments to make to get things working nicely. Some examples are below.


When declaring variables on an object, we were using the Array keyword to denote any kind of array, like this:


colours: Array;

What we should have been doing is using the generic version of Array to specify what type of Array we were looking for, like so.


colours: Array<string>;

Note, you will probably have to do this for any use of JQueryPromise, too, as that seems to require a generic parameter.


Something possibly Backbone exclusive is changing the way we were doing our urlRoot for our models. Before, we had loose as a function of our model:


urlRoot(): string {
     return apiUrlPrefix + '/stuff';
 }

This was causing conflicts with the ready-made Backbone Model variable, for whatever reason, so we had to move declaring it into the constructor, like this:


this.urlRoot = apiUrlPrefix + '/stuff';

In some files, we were getting JQuery to play nice, like this:


var $ = jQuery;

It seems as though after the update, this was getting in the way and removing this helped us along too.


That's not an exhaustive list of code pitfalls you'll come across, but these were the ones that got us.


Changing our references

It seems the way we were doing the references was a little out of date. According to the Typescript 0.9.5 announcement on the Typescript blog, the _references.ts filename is now special as well, and will be picked up by the Typescript compiler and inserted to handle the references. This means manually referencing this file at the top of our tests seemed to be duplicating things, so we removed the references.


We were also unsure whether referencing the lib (actual .js files) as well as the d.ts files in our references file would anger the compiler. e.g. We would have:


/// <reference path="../../../../MainProj/Scripts/Typings/jquery-1.9.1.d.ts" />
    ...
    /// <reference path="../../../../MainProj/Scripts/Lib/jquery-1.9.1.js" />

So we decided to take the lib reference out. By happinstance, I decided to comment out the lib references in a block comment. I was unaware at the time that this would mean Typescript would ignore them at compile time, but Chutzpah would still use them. This was a stroke of luck, since we would have still needed the lib files for Chutzpah to execute its tests. To formalise this, we decided to use the chutzpah_reference tag for lib files, which does the same thing, but in a more obvious fashion.


/// <reference path="../../../../MainProj/Scripts/Typings/jquery-1.9.1.d.ts" />
    ...
    /// <chutzpah_reference path="../../../../MainProj/Scripts/Lib/jquery-1.9.1.js" />

Conclusion


Finally, after all of those steps, we can build our project with no errors. Our tests run and pass nicely and our application works as it did before the Typescript update. High fives all round!


I wanted to share this experience in the hopes that it will help anyone who finds themselves running into some Typescript update woes. If you've still had no joy after reading this article, keep plugging away and hopefully something will click into place!


Happy Typescripting

No comments:

Post a Comment

As always, feel free to leave a comment.