The advent of Angular 2.x makes many teams considering to adopt TypeScript in their projects. The same goes for my team even we are still on Angular 1.x.
Upon research, we found that TypeScript is very attractive. It provides strong typing which allows us to detect type-related bugs early and nicer auto-completion. In addition, the syntax is cleaner for modularization and OOP.
This doesn’t mean that TypeScript is not good (and I would never dare make such a bold claim). But it was because it didn’t suit our team. The benefits we received did not outweight the price we had to pay.
Eventually, I think we would adopt either TypeScript or ES6 in the end. But it is not now.
There are numerous blogs explaining how awesome TypeScript is, so we will skip that. This blog will discuss about the points you should carefully consider before adopting it.
- Do you really need strong-type?
- Is your team good enough with build tools?
- Can you accept more complicated build process?
- How do you execute your unit test and debugging?
I would try to stay neural and objective as much as possible. I will be very clear if any idea is my personal opinion.
Points to consider:
1. Do you really need strong-type?
Let’s revisit the benefits of strong typing:
- Safety & early bug catch
- Better IDE assistance (e.x. auto-complete, refactoring)
A way to measure this is asking your team “How often do we found bugs that are related to wrong type?” (Undefined error, etc.) If the answer is “Meh, not really. Our unit tests catch most of them already”. Then the benefit might not be as much as expected.
3. Is your team good enough with build tools?
You will never get the build process right in the first time. During the first months of adoption, your build tool will be unstable and require a lot of tweaks. Be prepared for that. If your team members cannot fix some basic issues in build tools you use, the development will be blocked and the productivity will suffer. Be prepared. You should have more than one person who are good with the build tools to avoid bottleneck
If you rely on another team to tweak a build tool for you, be careful. At least, you should be able to configure your development cycle build in your own team.
In short, your productivity will most likely be impacted more than you initially estimate.
4. Can you accept more complicated build process?
Your unit test & “grunt serve” will be run on transpiled JS code. When you run and debug your application, you probably need to run it on a .tmp folder with sourcemaps.
If you use Karma, the TypeScript pre-processor https://github.com/sergeyt/karma-typescript-preprocessor is handy. It transpiles your *.ts files when Karma is run. Then it deletes them after the testing competes. However, I found some cons in using this plugin.
- It unnecessary copies and create a new .ktp.ts file (https://github.com/sergeyt/karma-typescript-preprocessor/issues/34 ). This slows the unit test. Plus, your ‘grunt serve’ and IDE with watch feature will detect these files and go crazy.
- You have to ensure that all ///reference are correct or it will throw a hellish amount of errors (https://github.com/sergeyt/karma-typescript-preprocessor/issues/43 )
In the end, I removed this preprocessor and use Grunt to perform transpilling step manually to .tmp folder. Then the unit test task runs unit test on that .tmp folder.
Alternatively, you can leave it to your IDE (IntelliJ, VS Studio) to do all these jobs. The support for IDE has been improving at a very quick speed. So you probably have a very good TypeScript support by the time you read this blog. Still, you will eventually need the grunt script for running on the build server. And, in my opinion, using multiple ways of building in the same project usually leads to a trouble in long term.
Finally, there is no tools that could provide a coverage report in TypeScript. (I did my research around Sept. 2015) So we need to do this in the transpilled JS. Thus, the coverage report is quite useless, we could only use the coverage percentage. Not a big deal if your team doesn’t use coverage report.
To summarize, the additional transpilling step affects us more than we expected. In your case, make sure to do your research carefully to avoid any nasty surprise along the road.
5. How do you execute your unit test and debugging?
To debug in TypeScript, you need a sourcemap. This can be configured in your build tool. It is very easy if you debug on your browser. But what about your IDE? Can you debug with Grunt/Gulp or you must stick to what your IDE provide?
If your team uses IDE for debugging, ensure that it has sourcemap integrated and can debug TypeScript on the fly.
One pain point we experienced is that there is no TypeScript debugging support for Karma plugin in our IDE (IntelliJ/WebStorm). Ideally, unit test should be simple and not require debugging. Unfortunately, our world is not ideal. The unit test in the legacy code might break and it is usually not clear what exactly the unit test wants to test. As a result, we were forced to the primitive and inefficient console.log(). That eats us a lot of time.
When people talk about adopting TypeScript, they usually focus on benefits. Hence, we classically underestimate the time we need to spend for learning and adjust our build tools. There is a cost we need to pay and it might not worth the benefits.
Nevertheless, I think that our choice on adoption was the right decision. We never know till we try. And we tried first on a new codebase, so the cost for reverting back was not high. The experience we earned will make us better in adopting new technologies in the future.