Note: I may be a bit biased towards Typescript. There’s no project that I start where I prefer JS to Typescript.
What is Typescript?
Then, why do we use Typescript at all?
How does Typescript do that?
But with Typescript, we can restrict this behavior by explicitly declaring a type for a variable. If we try to assign a string to a variable of type “number,” it generates an error.
aNumber variable to represent an object. While it isn’t an error that would crash the program, it beats the purpose of using variable names to self-document the code.
Typescript easily solves this issue by defining the type of the variable during declaration so that it can’t be assigned to a value of another type.
If another developer has access to this variable in your program, they can now rely upon its value being a number exactly as the name suggests.
In this case, the
Again, Typescript has the solution to this problem.
Now, this code may not make sense to you at the moment. But note how it ensures that the type of the variable passed is of the type Person, which is defined at the beginning.
Using Typescript will take away hundreds of careless coding mistakes from your program and prevent you from having to pull your hair out every time you encounter the silliest of bugs. It will also make your code better self-documented and increase its maintainability.
Using Types with Typescript
Typescript has a number of basic types that are pre-defined. Number, string, boolean, and array are a few examples of them.
You can find the complete list of basic types in the Typescript documentation.
Here are a few examples:
Similarly, try to avoid using a union of types, but if it is unavoidable, limit the number of types allowed in the union as much as possible.
Declaring custom types
Remember how I used a type called Person in a previous code example? Person is not a basic data type in Typescript. I created the Person type according to my requirements to use it as the type of parameter accepted by the given function.
We use interfaces to define the basic structure of a new type we are introducing to the application.
Now, if we create a new object of type, it should have the fields name and age within it. If not, Typescript throws an error.
You can also define optional fields inside an interface.
You can then use a custom type as the type of field when defining another type.
In Typescript, you can inherit the properties of another type by extending its interface.
Assume that your application needs two different types, Person and Employee. Since an employee is also a person, it makes sense to inherit the person type’s properties when creating the Employee interface. It prevents code repetition.
You can quickly achieve this by extending the Person interface.
Function parameter types and return types
Similar to variable types, you can define types for function parameters and return values. While the parameter type is declared next to the parameter name, the return type is declared just before the curly braces.
With the type of the parameter and return value defined, we can guarantee that you or anyone else using this function won’t accidentally pass an object that doesn’t have the characteristics of the Car type.
You can also guarantee that the field
Similar to variables, you can define the return and parameter types as a union of several types.
When you declare the accepted parameter or return type, objects of types that extend the initial type’s interface are also accepted as the argument or the return value.
With Typescript, you can define generic variables just as easily as what we have covered so far. If you are defining a generic function, you can use it to process data that belongs to any of the built-in or custom types.
What if you use the ‘any’ type instead of generics?
Of course, you can change the above function to accept any type of arguments using the ‘any’ type.
However, this method doesn’t preserve the type of data passed on to the function. Instead, it records every argument passed as belonging to any type. Besides you should avoid the use of
With generics, though, you can preserve what type of data is passed on to the function. If you want to change the function logic according to the type of data passed, using generics is better than accepting data of any type.
Using type aliases
When a particular field you want to use in the application could belong to one of several types, you can define its type as a union of those separate types.
Now, you won’t have to use a long union of types. Also, if you want to make a change to the return type of the function in the future, you now have to change only one line of code.
When one type is defined by extending another’s interface, the generated relationship between the two gives us permission to convert objects defined in one of them to another.
Take the Car and ImportedCar types I defined before. First, I’ll create an object of type ImportedCar and see how conversion works on it.
This code compiles without an error. It makes sense that this conversion works because the ImportedCar type already possesses all the fields defined in the Car type.
If we try to access the manufacturer field defined in the object before the conversion, it generates an error because the converted object is of Car type.
This article was originally published on Live Code Stream by Juan Cruz Martinez (twitter: @bajcmartinez), founder and publisher of Live Code Stream, entrepreneur, developer, author, speaker, and doer of things.
Live Code Stream is also available as a free weekly newsletter. Sign up for updates on everything related to programming, AI, and computer science in general.