New Series about TypeScript

Time to start a series about using TypeScript for creating large scale web applications.

In the recent months there was not much I could blog about. The main reason for this is that most/all of my current work is under NDA. That's a pity and I still hope that some of the parts will be open-sourced soon. However, with the large scale refactoring still going on I finally had the chance to use TypeScript on a massive web application. There is plenty of good stories to be told for that - so why not make a small series out of it?

I started advocating TypeScript right after it was initially released to public. I gave a talk at the WebTech Conference 2014 in Munich. At this point in time I was still in doubt if the rather anti-Microsoft based web community would embrace it (but I was not doubt about its potential). Luckily, my doubts have been unjustified in retrospective and TypeScript is a huge success. Even shops that are (at their core) quite against big companies (or specifically Microsoft) embraced this technology. So yeah, I couldn't be happier about the recent developments.

Still even though I used TypeScript for some personal projects, articles, and consulting, I never got the chance to apply it to a massive web app. There are plenty of reasons for this: For once these massive web apps are usually organically grown, i.e., they started with something before TypeScript was born or in fashion / accepted. Another reason is that there are not so many truly large web apps (we talk about several 100k lines of code here) out there. In the recent project we sit on roughly 300k lines of code (total). I would consider that a large web application (the minified production boundle is 5 MB, the core alone has 30 MB in a development (i.e., non-minified, but already compiled) bundle.

In the upcoming weeks I will create one or two posts per week (hopefully!) containing one to multiple (larger or smaller) TypeScript tips. They could be rather basic, such as the right usage for type vs interface up to tooling determined (how to share global interfaces without importing them explicitly) and more advanced (using generics to achieve fully flexible factories and typing systems). I will try to bring some code and examples with every post.

Even though this post is only the announcement of the series and not its start, I would still like to present my current approach for refactoring existing large scale web applications to TypeScript. Ideally, I want to follow the following process:

  1. Integrate TypeScript in the toolchain (e.g., if its Webpack, have the right loader for such files - maybe use tricks to speed it up or do only a subset in it)
  2. Introduce TypeScript to islands in the application (e.g., a module without any other internal imports - external imports should either have their typings installed or created manually)
  3. Always try to expand the support, i.e., convert other files when they only depend on typed files
  4. Write new modules exclusively in TypeScript

Previously, the process has been quite hard as TypeScript was mostly a all or nothing solution (even though claimed otherwise). This meant that once you renamed a couple of files (from js/jsx to ts/tsx) we had to fully swap. Here is where TypeScript did not like many things in the existing codebase. However, with the latest releases that changed. TypeScript introduced an allowJs flag that makes mixing not only possible, but still provides the type inference that will yield many of the mistakes that have been hidden previously. So the incremental approach is now better than ever.

There is one downside of this ideal approach: It still allows / encourages adding pure JavaScript to existing JavaScript files. Therefore, if we can allocate the time we should fully move to TypeScript. This move can partially be automated (renaming of files) and will pay off in the longrun.

The hardest part in such a refactoring is the organizational effort. It needs to be coordinated to:

  • Include typing for all external dependencies (there could be O(100) used dependencies)
  • Share typings between files
  • Potentially, later on publish a d.ts for the whole solution as seen externally
  • Move some special constructors that are not very typing friendly to TypeScript

The latter three will be discussed in the series even though for the last bullet point there is no one solution. Still, I can try to share my insights with the hope that they are being useful to the reader.

Looking forward to sharing some good large scale development with TypeScript stories with you!

Created .

References

Sharing is caring!