Typescript is Just JavaScript right?
TypeScript is a relatively new addition to the software development landscape. Released by Microsoft in 2012 as an extension to their Visual Studio, it has grown to enjoy a large community of users. Yes, TypeScript is in fact a superset of JavaScript. TypeScript is even designed to compile down to ES5 JavaScript(it also supports compiling to earlier ES versions). If you are familiar with JavaScript, you'll only need to know a few things to understand what is going on in TS code. Keep that in mind if you feel put off or intimidated by starting to use TypeScript. Transitioning to TS from JS is as simple as I will outline in this article.
Why Use TypeScript?
The development of TS started in order to address JavaScript's shortcomings when used to create large-scale applications. JS was not initially created to do many of the things that it has grown into doing. If you had told developers in the 90s that it would one day do something like run a server, you would have likely received some very strange looks. But, the diversity of uses for JS continues to grow. To deal with this growing complexity, Microsoft decided to incorporate some useful features from other languages like the C family, Java, Pascal, etc.
Type Annotation
The most important and useful of these features are centered around being able to declare the 'types' of variables and also of function return values. What this means is that upon variable or function creation, you can make a further declaration about what kind of data that variable or return value is supposed to be. This is called type annotation and allows for important features like static type checking.
Variable Type Annotation:
const aNumber: number = 1;
const anotherNumber: number = 2;
const aString: string = 'yay TypeScript';
const anotherString: string = 'is great.';
console.log(aNumber + anotherNumber);//logs 3
console.log(aString + ' ' + anotherString);//logs 'yay TypeScript is great.'
In order to annotate a variable, you make the declaration as you would in plain JS and then add a colon ':' after the variable name followed by the type that variable will be bound to. Types can be basic JS data-types such as 'string', 'number', 'boolean', or even 'null' and 'undefined'. The type 'object' can also be used, but be careful because TypeScript uses JavaScript's definition of objects, so 'null' and arrays will also be counted as 'object'. Arrays can be annotated using 'Array<T>', where 'T' can be any type. For example 'Array<number>', would be an array of numbers. There is also an alternative syntax for making an array annotation. You can make a type annotation and follow it with square brackets like 'string[]', which would be an array of strings.
As well as variable type annotation, TS also supports type annotation for the return value of functions.
Function Return Type Annotation:
function someFunc(num1: number, num2: number): number {
return num1 + num2;
}
Just like annotating other types, a function's return value can be annotated with a colon. This is achieved by adding the colon after the closing parenthesis of the function's parameter list. An important type for function returns is the 'void' type. Assigning a function's return type to 'void' declares that the function does not return a value. A simple example of this would be a function whose only action is calling a 'console.log()' on a value.
function logValue(logMe): void {
console.log(logme);
}
Once annotations are made, any variable or return that has a value other than what was annotated will throw an error at compile time. Here is where the value of TS starts to become apparent. Imagine writing a large application in plain JavaScript. There are hundreds of .js files in your repository. Unfortunately, an unforeseen bug has made its way into your code and now you have to find it..... It's not a situation that any developer would envy! A valuable tool for avoiding such a situation is TS throwing type errors at compile time. In other words, with thorough type annotations it becomes much more difficult to write 'bad' code.
Interfaces
An extension of type annotation is the ability to create Interfaces. An Interface is basically an object with annotated properties. By defining not only the types of an object's properties, but also the names of those properties, a developer can be quite specific about what objects are supposed to be. In this example, we define a simple interface in our function's definition:
function getName(objWithName: { name: string }): string {
return objWithName.name;
}
By defining the interface in this way, the function can only take in objects with a 'name' property that are type annotated as 'string' and the function must return a string. An Interface created in this way can take in an object with any number and type of properties as long as there is at least one 'name' property that has a 'string' type value. Interfaces can also be declared using the 'Interface' keyword and annotating the Interface's properties.
interface Location = {
latitude: number;
longitude: number;
}
function locationToString(coordinates: Location): string {
return `${coordinates.latitude},${coordinates.longitude}`;
}
Here we are creating an Interface that defines an object that has latitude and longitude properties that are both numbers. Assigning the parameter 'coordinates' to the type 'Location' requires that the 'locationToString' function take in an object that contains the 'latitude' and 'longitude' properties and that both properties are numbers. The return value has also been annotated to be a 'string' type. The ability to define Interfaces as a type allows for very specific definitions of objects. Because Interfaces are used for defining objects, they can be used for defining anything that JavaScript considers an object. Specifically, Interfaces can be used to define functions and arrays as well as object literals.!
As you can see, the more details we add about the types of variables, properties and return values, the more strict our code becomes about what can be done with it. This idea is the core concept behind TypeScript. It's all about using specificity to help reduce errors.
Type Inference
Another useful feature of TS is its ability to 'figure out' the most likely type for the return values of functions. Basically it works something like this: If a function takes in two parameters that are both type annotated as 'number', and the function does arithmetic operations to those numbers, TypeScript will make a guess at the return value being a number. This feature can allow a lot of code to be statically verified with only fewer annotations.
Linting
Another powerful aspect of developing with TypeScript is the way it can be used with a linter. Linters are extremely helpful software development tools that go through your code and point out errors(as you are coding!). The format for what constitutes an error can be configured, so that you can define the style and depth of your linter. The @typescript-eslint/parser package, for example will give type errors as you type them! On top of that, TypeScript files that are open in Visual Studio also give you amazing features like showing function definitions on mouseover and if available, even displaying documentation! Example:
TypeScript is a powerful addition to the JavaScript family. The features I've covered here are only a fraction of everything that TypeScript has to offer. The usefulness of it is apparent and its incorporation into large projects, like libraries and frameworks(Angular and RxJS to name a few), makes it a 'must learn' for any serious JavaScript software developer. Thankfully, the time it takes to learn TS in order to incorporate it into your code is very short.!
Oh and did I mention?...TypeScript is open-source. :D
Top comments (2)
Thank you for sharing such a helpful article!! :)
Can you remove the #help tag from this post, please? It's reserved for people who are asking for help, rather than articles that are helpful 😄