Tuesday, 20 August 2013

I moved a 4000 line coffeescript project to typescript and I liked it

TLDR: jump straight to the TypeScript section
About 8 months ago I started a new complex web app in javascript, and it quickly grew out of hand.
It had:
  • a server with routes
  • a singleton object with state, logic and helper functions
  • a bunch of similar plugins that extend functionality
  • the singleton object lives both on the server and on the client
Very soon I decided that javascript allowed too much patterns. I wanted modules, classes and easy binding on the this keyword.
Someone recommended CoffeeScript and I went with it.
The codebase expanded to about 4000 LOC in a matter of weeks.


So CoffeeScript hm, what about it?

These are my experiences after maintaining a non-trivial coffeescript application for a couple of months.

Pros:
  • Programming was quicker, stuff you want is already in the language. (classes, inheritance, array comprehension, filters)
  • Less verbose.
  • for k,v in object
  • fat arrow
  • "string interpolation #{yes.please}"
Cons:
  • fat arrow is very similar to thin arrow, git diff thinks this sucks
  • syntax. The attempt of avoiding braces is horrible. Function calling is a mess.
  • It smells like ruby. I dislike ruby with a vengeance.
  • no more var keyword? This is disturbing and error prone, given its significant subtleties in javascript.
  • everything is an expression? I like to be explicit about return values kthnxbye.
The result: a buggy codebase that feels scary, lots of unsafe monkey patching, coffeescript that seems to disagree with the idea of coffeescript.


TypeScript

When I started this codebase TypeScript had just launched. I deemed it a bit too experimental to work with, but last weekend I decided to give it a go. On Sunday I did git checkout -b typescript-conversion, installed the typescript syntastic plugins and started up vim. Fourteen straight hours of refactoring later it was done and 4238 lines of coffeescript had turned into 6145 lines of typescript.

I compiled all the .coffee files to .js files, removed all the .coffee files from the repo, and renamed all the .js files to .ts. Technically I was already done, as js is a strict subset of typescript, but doing everything typescript style was a bit more work.

Here are my experiences.

Pros:
  • fat arrow: removed almost all uses of self = this.
  • static type and function signature checking. I immedeately fixed about ten hidden bugs thanks to this.
  • classes and modules have never been easier
  • linking using tags
  • compiling linked files to one concatenated file out of the box using tsc --out
  • aim at ecmascript 6 forwards compatibility
Cons:
  • slower tooling (vim syntastic takes about 3-5 seconds after each buffer save)
  • no way of doing stuff like for k, v in object
  • no string interpolation
  • no automatic ecmascript 3 compatibility layer (monkeypatching Array with indexOf etc.)

Conclusion


I really really really like TypeScript. My project feels really clean, I see lots of room for improvement (and this time I know where to start). For larger codebases typescript will greatly improve maintainability.

If you work on a large codebase you can either automate testing, enforce developer discipline or move to static typing and a compile step. I think the last option is greatly preferred.