My TypeScript journey
It’s been some months that I’ve been programming with TypeScript. At first I didn’t want to switch to TypeScript, but I had to work on a TypeScript project. Fortunately it wasn’t that hard to understand its logic. The reason was that it was a TypeScript project with a lot of ‘any’ types in it! So honestly there was no type checking. JavaScript code written in .ts files. That was hilarious. I started refactoring the project and used this opportunity to learn TypeScript. I’m still trying to learn TypeScript best practices to use them in modern front-end frameworks and libraries. In this article I want to give you an overview of TypeScript, how it works, some of its features and best practices that I’ve come up with.
What is TypeScript?
TypeScript is a superset of JavaScript. With that being said, let’s raise a question. Do browsers understand TypeScript? I can answer this question by a big NO but I’d like to put it this way: Not yet! TypeScript compiles down to JavaScript, so that browsers and runtime environments like Node.js could execute it.
TypeScript adds type checking feature to modern JavaScript language. It doesn’t mean that JavaScript knows nothing about types. JavaScript is a dynamically typed language which means you can assign a different type of data to a variable later in your code. It is resolved at the runtime. The typeof operator proves that JavaScript knows well about types. TypeScript on the other hand is statically typed. Type checking is resolved at the compile time. I think this is a cool feature because it lets you avoid many bugs during your development.
More in the details…
So far we know in the end everything is JavaScript. So how does that happen? Well it all happens during the development process and you are forced to be clear regarding to types. We are looking at a step behind the code runtime which means we can have a flexible tool to avoid some bugs earlier in the development. If you look at the compiled result, you won’t see anything special or new to JavaScript. All those special syntax introduced by TypeScript will be gone. Because they were all intended to help you during the development and I repeat: In the end everything is JavaScript!
There is another thing that might interest you. TypeScript can compile all your JavaScript modern code (ES6) to old JavaScript code if you set your desired target in your tsconfig file. This is far beyond compiling only TypeScript features to regular JavaScript. Pretty interesting huh?!
Another good news for developers who come from other programming languages is that you can have tuples, enums and generics in TypeScript as it is not supported specifically in JavaScript.
Interesting notes on TypeScript
Let’s take a look at some TypeScript features and best practices you could use in your project:
Explicit type assignment is one of the most important features that TypeScript gives you. But be careful to not overuse it. Sometimes TypeScript can understand the type of a variable or function by its type inference. Let’s say you declare and initialize a variable in your code. TypeScript knows this type and you don’t need to assign its type explicitly unless you are planning to deal with more complicated types of data. Sometimes this is a good practice to let TypeScript’s type inference do its job.
Avoid ‘any’ type! If you use it, so what’s the purpose of coding with TypeScript?! You are disabling the most important feature of TypeScript. It is useful when you are in the process of migrating a JavaScript project to TypeScript. Use ‘unknown’ type instead if you don’t know what a type might be.
Use Tuples or Enums if you have a real use case in your project. Most JavaScript developers are not familiar with these data types and probably have used some patterns to implement Tuple or Enum functionalities in JavaScript. But it’s time to avoid those patterns and use these data types in a TypeScript project.
Literal types are useful when you know there are limited possible values for a variable. Your IDE might give you a good support of auto suggestion while assigning value to these kind of variables. A very good use case is assigning literal types to custom React components props. For example you have a custom icon component and want to configure its size with a ‘size’ props which can have only three values: ‘large’, ‘middle’ and ‘small’. This is where you can use literal types.
Most of the time type aliases help you write clean code.
Interfaces are useful for objects’ type checking. You can use them interchangeably with custom types which we learnt previously but they are not exactly the same. Interfaces are aimed to be used with classes. They are used to share a specific structure and functionality between classes.
In this example, we check if class Sonar is satisfying interface Pingable with the implements clause.
If you encounter a situation that you need a type to be a combination of multiple types, intersection types is out there for you. Although if you are using interfaces, you could achieve this by extends feature.
Type casting allows you to force TypeScript about a type. This is very useful when you are interacting with data which could possibly be null or undefined and you know it is not. Do not use this feature if you are not sure about the type of a value!
Function overloads are useful when TypeScript’s type inference can’t help you with function types. Let’s say you consider a function to accept some arguments and return values with different types. This is how you would declare it:
Dealing with null or undefined values are always challenging especially if you are fetching data from the servers in the front-end. Well TypeScript has some good news.
With optional chaining you can access a parameter conditionally if they’re not undefined or null.
There’s another interesting feature. Nullish coalescing lets you set a fallback when a value is null or undefined. There’s something important to keep in mind. We are just talking about null and undefined values and not falsy values like 0 or Nan.
Wrap up…
These features and best practices are very bold and you’d absolutely encounter them after some time if you start doing projects with TypeScript whether you are a front-end engineer or back-end engineer. Of course this is not everything TypeScript offers. I’d recommend more advanced features like generics and decorators for further reading.
There is another thing that you should be aware of. TypeScript might increase the development time because one should spend some time on type checking. On the other hand, type checking helps developers avoid some bugs during the development process. So this is your call. It completely depends on the scale of your project and your preferences whether to go with TypeScript or JavaScript.
Let me know in the comments if you’ve found anything interesting about TypeScript.