Converting an existing Angular JS application to TypeScript
Whilst there are various guides out there to creating AngularJS projects with TypeScript from scratch, little has been written about porting existing applications, so what follows is a summary of our approach and some of our findings.
We used the obvious choice of grunt-ts to handle typescript compilation. Rather than use a globally installed version of the TypeScript compiler (tsc), we used npm to install tsc locally to the project, this way the TypeScript version is controlled within the project environment and builds will be reproducible.
For linting tslint proves comprehensive and an easy replacement for jshint, hooked into our build system via grunt-tslint. Testing remains handled by Jasmine/Karma with test tasks now involving a compilation step for both tests and testees before testing.
First we need to retrieve TypeScript definition files that will give us typed interfaces to the various components on which we depend, in our case Angular and angular-translate for the main application and Jasmine for the tests. These definition files can be manually downloaded however we used the TSD typescript definition manager which automatically downloads definitions specified in a configuration file. This allows us to avoid checking definition files into version control, in a similar way to which we use npm and bower to manage packages. Unfortunately for those coming from npm the TSD tool can be a little unintuitive, and it it unfortunate to have to introduce yet another package manager, but at this point there appears to be no superior option.
With definition files in place, all that remained was to rename all our .js files .ts, easily achieved with a bit of command line voodoo, and insert references to the required definition files. The syntax for these references is a bit odd but seems to be a legacy of TypeScript's integration with Visual Studio, for example:
With all this in place we were able to compile and run our test suite to make sure everything still worked as expected. This represents the minimum needed to port the entire application to TypeScript, however at this point we aren't actually leveraging any typescript features within our own code, to get real value from TypeScript we need to do a couple more things which will be detailed in part 2.