Book Image

Refactoring TypeScript

By : James Hickey
Book Image

Refactoring TypeScript

By: James Hickey

Overview of this book

Refactoring improves your code without changing its behavior. With refactoring, the best approach is to apply small targeted changes to a codebase. Instead of doing a huge sweeping change to your code, refactoring is better as a long-term and continuous enterprise. Refactoring TypeScript explains how to spot bugs and remove them from your code. You’ll start by seeing how wordy conditionals, methods, and null checks make code unhealthy and unstable. Whether it is identifying messy nested conditionals or removing unnecessary methods, this book will show various techniques to avoid these pitfalls and write code that is easier to understand, maintain, and test. By the end of the book, you’ll have learned some of the main causes of unhealthy code, tips to identify them and techniques to address them.
Table of Contents (11 chapters)

About TypeScript

What Is It?

TypeScript (https://www.typescriptlang.org/) is a superset of JavaScript. That is, it's JavaScript with a bunch of additional features. After you've written your code, it compiles into JavaScript.

TypeScript was created by Microsoft and led by Anders Hejlsberg (who was one of the core members of the group that formed the C# programming language, among others).

TypeScript's primary features and benefits include the following:

  • A fairly advanced type system
  • Support for future and bleeding-edge JavaScript features
  • Fantastic support for developer tooling inside IDEs

What's All the Fuss About?

TypeScript has gained a lot of traction in the past few years. In the 2019 Stack Overflow Developer Survey, TypeScript was rated as the #3 top-loved programming language (https://insights.stackoverflow.com/survey/2019#most-loved-dreaded-and-wanted)!

Why do developers love it so much?

From my own experience, it's because JavaScript (due to its dynamic nature) allows for some strange kinds of code. Also, because it's compiled at runtime, most bugs are discovered at runtime (in certain production scenarios, this can be too late to catch bugs!).

With TypeScript, on the other hand, you can define solid contracts by using types (classes, interfaces, types, implicit method return types, and so on). This enables the IDE you are using to immediately detect certain kinds of bugs as you type your code! It also makes your code more predictable and less error-prone since you have guaranteed method return types, for example.

Note

I remember the first time that I introduced TypeScript into a real-world project – it increased my productivity tons! I discovered bugs that I had no idea existed, either.

TypeScript versus JavaScript

I'd like to make a quick comparison between some vanilla JavaScript and TypeScript to give you an idea of what I've been talking about.

Let's take some valid code in JavaScript:

const myData = getMyData();

How do I know what the getMyData method will return? Will it return an object? A Boolean?

If it does return an object, how can I find out what the properties of the object are?

Other than digging into the source code for that method, I can't.

Inside that method, we could even do something strange, like this:

function getMyData(kind) {
    if(!kind)
        return false;
    else
        return { data: "hi" };
}

So... sometimes, this function returns a Boolean and other times it returns an object?

I've seen code like this in real-world production code bases. And yes – it's very hard to understand, debug, and test and is very prone to errors.

Using TypeScript, you can lock down the return type explicitly:

function getMyData(kind) : object {
    if(!kind)
        return false;
    else
        return { data: "hi" };
}

This would not compile since the method signature says that the method should always return an object, but the code can return a Boolean and an object.

Let's look at another example:

const user = {
    emailAddress: "[email protected]"
};
emailUser(user.emailAddress);
user.emailAddress = 2;
emailUser(user.emailAddress);

The second time we call emailUser, we are passing it a number instead of a string. That's what I mean by strange code.

In TypeScript, this would throw an error at compilation time (and in your IDE as you type).

You would find this issue immediately as you type. However, in JavaScript, you wouldn't know about this until you tried to send an email to a user at runtime.

What if this bug ended up only happening in certain production scenarios? In this case, by using TypeScript, you could avoid this error before you even commit the code in the first place!

Why I Chose TypeScript for This Book

I chose TypeScript as the language to use for this book because it has much in common with dynamic languages such as JavaScript, yet it also has common features from object-oriented type-safe languages such as Java and C#.

It has a good blend of object-oriented tools, functional tools, and the ability to still harness the dynamic nature of JavaScript if needed.

Most of the techniques in this book are generic and can be applied to most other programming languages. TypeScript just happens to be a good middle ground to use to showcase these problems and solutions!