TS Future

Depending on who you ask, TypeScript is one of the best things to happen in the JS community. Or it is just cramping on developers’ styles and making it harder to code. A lot of people have strong reactions to it.

I’m definitely not here to persuade you to use TypeScript in your projects and work, if I’m able to that would be a nice benefit. Ultimately you should decide if this is something worth learning for you and your career.

My personal experience using TypeScript with React is part of what has made me so passionate about TypeScript and eager to share knowledge with anyone who asks. It has helped me write cleaner code and, in the long run, be a more productive programmer.

TypeScript – Motivating Example

Toss React aside for a second. Let’s go through some elementary functionality to help us understand what TypeScript helps us with.

We’re going to start with a function that queries a dataset of users, which we will call findUserById. We pass in an id as an argument and we get the user object in response.

All well and good. You might think there’s nothing wrong here at all, and you’re correct! But let’s consider what would happen when you have that function in the context of a large application, perhaps intermixed with other functions from which we derive the id we’re looking for.

What if we actually receive an id as a string when we pass it into the function? We can simulate that.

Unless we we’ve been very diligent in unit testing our code, it’s highly likely a bug like this will surface at some point. This is also fine, in a sense. But how do we want it to surface?

Using the example above, there is a non-negligible chance that it will surface during runtime, possibly crashing an app or site.

Alright. Now let’s take the simplest step of converting the file name where that function is located to .ts (if you’re running this on your own, assumes you have TypeScript installed. I recommend learning TypeScript using VsCode as it makes TS development environments easier to set up).

When we try to compile and run this, we receive an error that "Parameter 'id' implicitly has 'any' type.". Okay, so let’s clarify what id‘s type is.

Aha! Now our bug has surfaced. And even better, it surfaced before we tried to run the underlying JS. This is a compile-time error. With the right tooling, it’s actually more like a dev-time error. In VSCode, this message surfaces right away. We have potentially saved a lot of time and headbanging.

So if we know that id will come to us as a string, what should we do? One option is to cast it.

In a more sophisticated system you would probably want to have things set up such that an id at that point of usage would never be a string but that’s beyond the scope of this simple example.

Overall, this is TypeScript usage at its very basic. One doesn’t need too much knowledge to understand what is happening. We are merely annotating the type of the parameter or variable using : syntax.

TypeScript takes care of the rest. It will check that you are using this function consistently with its annotation. Basically, it will check that you are telling the truth.

Benefits of TypeScript

The example above is illustrative of two of the main benefits of TypeScript.

  1. Type Safety: This is what helps prevent you from lying to your code. You can code with the confidence that a value that is supposed to be a number is in fact so.
  2. Documentation: Self-documenting code is the best code. This is precisely what we achieve with TypeScript usage. It is, all of a sudden, much easier to open a file in a large codebase and at a glance get a sense of what’s going on.

Why You Should Start

All JavaScript is valid TypeScript. Which means that if you already know JavaScript, you can get started immediately.

This was the mindset that personally helped me onboard to TypeScript quickly. It’s “JavaScript + extras”. If you think that way, you can start with a limited pool of TypeScript functionality and get very far.

Then you can expand your knowledge iteratively as you see fit.

Optional Static typing

A brief note on the basic types you can use with TS:

  • boolean
  • number
  • string
  • Array
  • any
  • void
  • null
  • undefined
  • object

This is Fine
Me before discovering TypeScript.

React + TypeScript

Once you understand the basics of TypeScript, there is not much that is special about its usage with React. Let’s look at an example App component in JSX.

Nothing crazy so far. What happens when we convert it to .tsx extension?

This is the exact same TS error we received earlier with our id. So let’s define our props. But this time we’ll add an extra level of modularity :).

We created a “type variable” of sorts (identified by the keyword type). It’s a simple way to abstract out type logic and definitions that you may want to reuse. Just like a regular variable!

What about State?

Let’s say we wanted this to be a class component with state in TypeScript. Say a counter. Here’s how we would do that.

There is one new concept here. That is the insertion of our type definitions where the class itself is defined (Component<AppProps, AppState>). We are making use of a common feature in strictly-typed languages called generics.

If that sounds all too crazy, for now the main thing to understand here is that our Component class which we are extending wants to know what type of state and props we are using so it can help us check that we’re staying consistent with those things!

That’s it!

I hope this was helpful to someone with limited exposure to TypeScript. One final thought. The point of TypeScript is not to turn JavaScript from this:

console.log("Hello World!");

to this:

public class Hello {
  public static void main(String[] args) {
    System.out.println("Hello World!");
  }
}

We all love JavaScript for its quirks and that it’s a highly flexible language. TypeScript respects most of that flexibility, but allows you to do everything in a safer way.

As an extra challenge, feel free to rewrite the App class component in TypeScript using Hooks.

Resources