We at bet365 have always had a strong relationship with flash — it has powered all of our In-Play apps since their conception, as well as our whole desktop website. Sadly, though, it wasn’t to be and even in the best relationships there comes a time when you just need to move on.
Unfortunately, at the time, the language was still in its infancy and there were uncertainties around the level of support it would receive from Microsoft. The decision was made to postpone adoption until the language itself had reached the big 1.0.
As it turned out, TypeScript still fit our needs as a large development team and having had the opportunity to have worked with what was now turning into a large Raw JS codebase, we were starting to miss some of the benefits from more strongly-typed languages we’d used in the past, such as AS3 and the ASP.NET family of languages.
This was all fresh code. This was all code that had been subject to a pretty tight new set of authoring standards. A single class per file, logically namespaced, with well-defined naming schemes and all heavily documented using the VSDOC comment syntax, including type information for reference. Yet still, the bigger the codebase got, the harder it became to maintain and take the continuous improvement approach to our code as we had become accustomed to in the past.
It was decided to see if a script could be written that simply converted the *.js classes into *.ts classes. As the codebase had been written using the same prototypal inheritance model as TypeScript, and the coding standards we had adopted at the start of development covered a lot of TS’s language constructs via inference (access modifiers, types), we had the finalised script after just a few days.
The script, which was written in TypeScript, managed about 85% of the conversion process. It covered:
- Import statements
- Conversion of comments from VSDOC to JSDOC
- Class member properties with type definitions
- Static properties with type definitions
- Method signatures with type definitions for parameters and return types
- Public & private access modifiers inferred from the naming scheme
- Protected access modifiers for a whitelist of methods/properties
- Renaming the file in source-control to preserve history
The remaining percentage would be tidied up by hand. This generally included creating any interfaces needed, re-formatting code to benefit from type-inference and lastly fixing any bugs the TypeScript compiler found along the way!
The latter was the first sign our decision to migrate the codebase was indeed a valid one. The bugs were just simple spelling errors in function calls or chaining to base methods that didn’t exist – things the TypeScript compiler is great at giving visibility on.
The process, including modifying our build systems, testing the build output and writing new interfaces, took around 10 days. So having the script do most of the legwork enabled us to average around 6,000 lines a day during the conversion itself.
Was migrating to TypeScript worth it?
Absolutely. There’s no doubt, the answer is yes. Working on a large codebase that’s growing as fast as ours, with multiple developers active across different projects, it’s very important to get the quality right up-front. Having a type system running checks that previously involved a very manual process in QA is invaluable. It also allows us to take a much bolder stance when designing new components thanks to the introduction of interfaces, which we use heavily.
Having learned a lot with TypeScript, we’re currently migrating our workflow away from being based around MSBUILD & Custom Visual Studio Plugins over to instead be based around Gulp & Node, so we’ll share more on that in the near future.