TypeScript – Help or Hindrance?
At 345 we’ve been using TypeScript for a while now. This started when we began using Angular 2 during the early Betas, and we’ve been experimenting with TypeScript on some of our other Node.js applications as well.
The time has come to ask the question: Is TypeScript a help or a hindrance?
What is TypeScript?
Why use TypeScript?
When TypeScript has been good
Angular 2 (https://angular.io/) runs off TypeScript. When you’re creating single page applications (SPAs) with Angular 2 the majority of the code you reference is the Angular 2 framework itself. The Angular model is consistent and well written, and as Angular provide the types for their framework the use of a typed language is natural and effortless.
The “linting” process, i.e. code checking, has been good in TypeScript. It has been easy to put in place rules that provide uniform-looking code that passes static code checks. Again, not saying tools for JS aren’t out there, but this has been good in TS.
When TypeScript has let me down
We build a lot in Node.js these days, as do many others. We rely heavily on NPM packages to pull in references, but with TypeScript you need to pull in the types for referenced packages in order to use them. Most of the types are out there because people have needed to use them for their own projects, and they create type definitions and upload them to opensource repos.
Types have therefore become a minefield of inconsistency, with the official types often not keeping in step with the versions of the packages they are supposed to reference. Furthermore, there’s a ton of lazy typings with “any” types used all over the place, negating the benefit of type checking in the first place. TypeScript 2 tidies up the type references significantly, and includes the addition of a type search (https://microsoft.github.io/TypeSearch/) and type references, but there are still problems with the availability of type definitions and the inconsistencies therein.
The massive productivity improvements you can get from using Node and NPM are dampened considerably by the TypeScript type restraints. While you could argue that this is a “good thing” because you get additional compile-time checks, you could counter that by saying that you should concentrate on test coverage instead.
TypeScript is very much an evolving language, and the ancillary components such as tslint (https://www.npmjs.com/package/tslint) are also moving rapidly. This can cause issues if you’re not pinning your versions and managing the transition from one to the other carefully. This is a configuration management activity that seems to bleed time over and over again if you’re not careful.
Limitations of TypeScript
Unlike true OO languages such as C# or Java, where an object can be properly interrogated to find the interfaces it implements and the superclasses it descends from, TypeScript is much more limited in this regard. You cannot check whether an object implements an interface. Given the purpose of TypeScript, this seems slightly crazy, but it’s true. You can only check whether an object is an instance of a class, because the runtime type checks uses class constructors. There is no type attributes associated with an object.
I’m mystified why the TypeScript designers didn’t take the opportunity to tag metadata onto classes so that it can be interrogated at runtime, but that’s another story.
In TypeScript you end up in this blind alley sometimes where you need to inherit a class just to add a new interface, and then you can’t type check your interface later. You end up spending time getting round the limitations of the TypeScript language in order to achieve things that are supported by the language you’re compiling to.
The major cost in almost all software projects is man-hours. Productivity is therefore paramount, and as far as I can see you lose a ton of productivity when you use TypeScript that you don’t seem to gain anywhere else. TS is the “type-safe tax” you have to pay on your project.
Some specific scenarios, such as Angular 2 apps, you may decide are worth it. I would advise anyone making a decision on TS vs JS to look very closely at the benefits you feel you’ll get and to try to measure the productivity gap between the languages.
Don’t use TypeScript because there’s a bandwagon. Use it because you have a reason to. If you don’t have a reason to, stick to JS and concentrate on mature dev practices and test coverage.