Why your Company should enforce TypeScript!

I recently read a right load of old codswallop on why you shouldn’t use TypeScript, and it inspired me to state some reasons why you SHOULD use the bugger.

If you’re in the trenches on a daily basis like me, trudging through knee deep, untyped clutter, wishing for an armistice, or at the very least the assassination of the previous developer. Keep your head up mate, there is light at the end of the tunnel, and one that isn’t going to end in life imprisonment.

Why TypeScript/Static Types are so good

Firstly, I’d just like to acknowledge, that yessss there are other alternatives to TypeScript for static typing and yessss there are some benefits to dynamically typed languages, but for the sake of this blog I’m going to be talking from the perspective of a programmer (me) who has converted a plethora of node apps to TypeScript, partly out of enjoyment and wholly because it is the right thing to do.

Compile time errors > Run time errors

Isn’t it wonderful when you code something up and before you even hit that run button your compiler’s moaning because you’ve done something wrong, thank you Mr Compiler you’ve saved me two hours of debugging, one mountain dew and a smack on the bum from the project manager who’s asking why the fu*k it’s taking you so long to do a ticket you said would only take half a day?

This is the magic of compile time errors! Every now and then you should type an appropriate comment to your compiler saying // thank you. Just to really express your gratitude, because before long compilers will have their own consciousness and they’ll really appreciate how you treated their predecessors.

So yes, using TypeScript is going to establish a pretty bloody large safety net for catching programming mistakes.

Suppose we had a very simple example which just adds two numbers

function add(first, second) {
  return first + second;
}

What if for some reason we call that function and pass in a string rather than a number?

add("10", 5);
// 105 

This is an exceptionally dangerous example as it doesn’t even give us a bloody run time error, it simply concatenates the string and the number. So that’s increased somebodies bank balance by more than expected, I wouldn’t mind these programmers working for HSBC.

Let’s rewrite this code as TypeScript:

function add(first: number, second: number): number { 
    return first + second;
}

Now if we do the same as before by passing in a string:

add("10", 5); ---Argument of type '"10"' is not assignable to parameter of type 'number'.

And we didn’t even click the run button, ahhh lovely.

Intellisense

This is one that seems to be completely forgotten about when debating whether to use TypeScript. Intellisense provides an absolute abundance of benefits that I am quite simply lost without it. It is a commodity that I have been so spoiled with from IDEs such as Intellij’s smart completion where it filters the suggestions list and shows only the types applicable to the current context, or Visual Studio Codes IntelliSense https://code.visualstudio.com/docs/languages/typescript. Without it my job is 10x harder/labourious, it’s like a roofer being told he’s not allowed to use a ladder anymore he has simply got to jump.

Other benefits include:

  • The ability to hover over a TS symbol to quickly see its type information and other relevant stuff.
  • The ability to view the signature information of a function without having to jump into it and remembering what types each param is.

Access new JavaScript features before they’re even supported! & Browser Compatibility.

What? What is this magic you speak of. Yes, TypeScript allows us to use the newest features of JavaScript even if your customer is using some dodgy browser. You can specify the target ECMAScript to make sure, according to this article all major browsers have very good ES6 support so if you’re transpiling to ES5 you’re making your code unnecessarily big and slow to support a minority of browsers. But, if you need to you have the option.

Strict null checks

This one might not be as sexy as using futuristic JavaScript features or the wizardry of Intellisense, but its importance (to me) is second to none. I cannot tell you how many times I have seen this error. cannot read property ‘x’ of undefined or even undefined is not a function. Provided you’re not using the any typed variable the chances of seeing these errors with TypeScript is very small, and blimey does that make me happy. No longer can you call a function that doesn’t exist without the compiler throwing a wobbly. You can go one step further and add –strictNullChecks to your .tsconfig which basically means, no mate, don’t you dare try set that variable to undefined or null. You can though, explicitly set a type as nullable.

With –strictNullChecks but no nullable flag on type:

let favNumber: number;
favNumber = 8 // Ok
favNumber = undefined;   // NOT A CHANCE MATE, SORT IT OUT (compiler shitfit)

With the nullable flag

let favNumber: number | undefined;
favNumber = 8;  // Ok
favNumber = undefined;  // Ok mate, but only because you have that undefined flag

Understanding the code

There’s one thing being able to read code, but actually understanding its intent is an entirely different ball game. Especially when using dynamically typed programming languages where you have to juggle around a number of potential unknowns.

A lot of people would/do argue that adding types reduces the readability of code by adding boilerplate. Okay, right, yes, there is some boilerplate I agree, BUT the boilerplate adds documentation it explicitly states the inputs and outputs of a function without any of this guessing shite, we KNOW it takes in an integer and returns a boolean.

Here’s a very simple example of juggling unknowns, this is some code I stumbled across in the trenches.

function getTimeAllowed(currentDate, caseLevel, customer) {
    // magic
    return x;
}

Just by taking a glance at the signature of the function we’re already dealing with three potential unknowns:

  • currentDate I immediately make an assumption that this must be JavaScript’s Date object (I was right).
  • caseLevel what could that be? Quick grep is this a caseLevel class? No? okay does it pass in a number? Oh the function that calls getTimeAllowed() just passes in a caseLevel as well, so I have to chase it further up the chain.
  • customer, I make a wrong assumption that this is a customer object. It was in fact the customer’s ID. This one is just a poor choice of variable naming by the programmer.

In the end, I get sick of the guessing and grepping I end up having to debug it and getting the application to the point where it calls the function, an absolute pain in the arse.

This is without even considering what the function returns, which is another kettle of fish. I ended up converting the application to TypeScript and this function looked like this:

function getTimeAllowedInDays(currentDate : Date, caseLevel: number, customerId: number) : number {
    // magic
    return x;
}

Write less tests.

Okay, so I encourage you to write tests I myself use TDD on a daily basis and would recommend every programmer to do so. Tests give you an abundance of confidence when doing a refactor as do types. But, in having types you don’t have to write as many tests. I have seen countless and I mean countless JavaScript tests where they test passing in invalid arguments, so passing in a string where it should be an integer. The programmer then rewrites the function to handle wrong inputs, which to me adds more boilerplate than TypeScript ever could. if (typeof day === “number”) { // no no no. If using TypeScript has just one purpose and that is to stop the writing of these pointless tests then to me, it’s worth it.

Conclusion

At the end of the day, people have their preferences. My preferences have been forged from the long lost hours of run time errors both at work and in my spare time. I can only imagine the sheer amount of money companies have spent on developers who are debugging a completely compile time catch-able bug. Which is why I think for the majority of scenarios (I’m sure there are some exceptions) TypeScript should be used over JavaScript.

Leave a Reply