JavaScript is arguably one of the most popular programming languages as of 2020 and its popularity is just growing day by day. The primary reason why it is so popular is because it is the default language of the web frontend. What that means is that browsers can only understand JavaScript and nothing else.
This unfortunate condition enforced every web developer to become a JavaScript developer. So as the web development industry demand grew for web developers, more and more people became the JavaScript developers.
At first, it seems like a good thing but it’s not that impressive. JavaScript, though it might be on the top of the popularity chart in terms of its use, but I would not use “popular” as the exact word to describe it.
JavaScript is not an old programming language like the C
or C++
programming language. Actually it was not even designed to behave like a general-purpose programming language. It was developed by Brendan Eich in 1995 for the Netscape browser in 10 days. It was supposed to be a scripting language to add dynamic behavior to the web page.
Many other browsers such as Internet Explorer adopted this language but with a different flavor of their own. That’s why it was needed to be standardized. The first official version of JavaScript (ES1) was released by ECMAScript back in 1997.
If you want to know more about the history of JavaScript, you can follow the video above. I have discussed how JavaScript works under the hood and different parts of the JavaScript engine in the “How does JavaScript and JavaScript engine work in the browser and node?” article.
In a nutshell, JavaScript didn’t get a good start. It wasn’t though as a general-purpose programming language until much later. In 2009, a bloke named Ryan Dahl created a backend software that had Google Chrome’s V8 JavaScript engine and it could run a JavaScript program using it.
Many people liked this idea, mostly the JavaScript developers I guess who got bored of doing the frontend web development day in and day out. This is how Node.js was born. It’s been 10 years and Node.js is still rocking.
From an online survey conducted by StackOverflow in 2019, JavaScript is the most popular language on the planet and Node.js deserves huge credit for this since it is the most popular tool (actually platform) as shown below.
💡 I like how Go (Golang) is also becoming popular despite being a new language. Go is a statically typed language, hence it wouldn’t be fair to compare it with JavaScript. I have a dedicated publication just for Go if you wanna learn it.
The picture above clearly states that JavaScript is heavily used but does that means developers like working with JavaScript? Well, in my opinion, JavaScript is fun but comes with a lot of sacrifices. Let me explain.
JavaScript is a scripting language that means it will be interpreted by a JavaScript engine in its original form (the source code). If you want to know how it is interpreted by the JavaScript engine, read the “How JavaScript works” topic of the WebAssembly introduction article.
Being a scripting language, it can’t be compiled to a compact binary executable that can run natively without an interpreter. Well, that’s not a big program. The big problem is type safety. JavaScript is not a statically typed language which means the data types are evaluated at runtime.
For example, if you declare a variable var x = 1;
, the type of the variable x
will be number
at runtime but you can also assign a new value to it of a different type such as a string
, for example x = 'hello'
. This behavior can cause a lot of issues if we are not being careful.
Since there is no compiler involved in the process of writing JavaScript, there is no way to prevent this behavior unless some error occurs at the runtime if we are extremely lucky to find that error.
The failure of Dart
Google being “Google” wanted to address this problem. The developers at Google worked on a statically typed language called “Dart” that was supposed to replace the JavaScript in the browser (and hopefully on the backend side too). They planned to ship a VM in the Google Chrome browser that could run (interpret) Dart programs natively. For legacy support, Dart could transpile to JavaScript until everybody (browsers) gets on this bandwagon.
💡 According to Wikipedia, it first appeard in October 2011 and the first official version v1.0 was released in November 2013.
This whole idea was laughed out and criticized by the developers. Since then Dart was scrapped as a replacement of JavaScript and became an exclusive programming language to write cross-platform native applications. Google’s Flutter framework uses the Dart language to make it happen.
💡 If you want to learn Dart, I have a dedicated publication for it.
The rise of TypeScript
Let’s come back to the question, is JavaScript popular? Let’s clarify it, is JavaScript loved by the developers? I don’t think so, at least not in its entirety and other developers seem to agree with this theory.
According to the same survey, JavaScript is not even in the top 10 most loved programming languages (well, it’s 11th). But TypeScript is 3rd in the list and first if we talk about just the languages that deal with JavaScript. So what is TypeScript and why the hell it’s so popular?
A team at Microsoft wanted to do something like Dart but they took a different approach. Instead of reinventing the language with a completely new syntax, they just amended the JavaScript syntax. Not only that, but they also made this new syntax optional. This is how TypeScript was born.
That means any JavaScript program is a valid TypeScript program. Due to this reason, TypeScript is also called the superset of JavaScript. You might have heard somebody saying TypeScript is just JavaScript with types.
So what is this new syntax and what are types?
Normally, you would write a JavaScript program like below.
// program.js
var x = 1;
var y;
console.log(typeof x, typeof y); // number undefined
x = "hello";
y = "world";
console.log(typeof x, typeof y); // string string
x = true;
y = x;
console.log(typeof x, typeof y); // boolean boolean
// number undefined
// string string
// boolean boolean
What we did in the JavaScript program above is just to create two variables x
and y
. The variable x
has an initial value of 1
which is a number
. The y
however doesn’t have an initial value. It’s initial value is undefined
.
Let’s imagine this program running in the browser (or on Node.js), what do you think will happen. Being the dynamically typed language, JavaScript will not throw any errors. First the data type of x
is number
, then string
when the string 'hello'
is assigned to it and then the boolean
when true
is assigned to it. You can see this from the output of console.log
statements. The same goes with y
. All these types are determined at the runtime.
What TypeScript did was to provide a compiler that can process this program and throws errors if it detects something odd with the program. This compiler is also called a transpiler since it outputs the cleaner JavaScript program.
At this moment, our program doesn’t contain any necessary information that can tell the TypeScript compiler about what is expected out of it. What TypeScript expects are the Type Annotations. A Type Annotation is an indication of the data type of a value.
// program.ts
var x: string = 1;
var y: number;
console.log(typeof x, typeof y);
x = "hello";
y = "world";
console.log(typeof x, typeof y);
x = true;
y = x;
console.log(typeof x, typeof y);
// Type 'number' is not assignable to type 'string'.
// Type 'string' is not assignable to type 'number'.
// Type 'boolean' is not assignable to type 'string'.
// Type 'string' is not assignable to type 'number'.
We converted the JavaScript to a TypeScript program by changing the extension from .js
to .ts
. Now your IDE can check for any errors even before you compile this program to JavaScript.
TypeScript installation (follow this documentation to install TypeScript) comes with the compiler that is accessible through the tsc
command. The tsc program.ts
command compiles the program.ts
file into p``rogram.js
file.
As of now, we can see the TypeScript compiler is displaying some errors in the console. If you see, the variable x
has been annotated with :string
. This is the type annotation we talked about. This annotation provides the data type of variable x
to the TypeScript compiler.
When the TypeScript compiler sees this, it assumes that x
will be string
during the lifetimes of this program. However, we have assigned an initial value of 1
which is a number
to it. This is not valid and it will complain about it in the compilation error messages as you can see.
The y
is annotated with the type of number
. Since it lacks an initial value, TypeScript compiler will watch out for any assignment statements that assign a value to this variable other than a value of number
type. Since we are trying to assign the value 'world'
of the type string
to it, this is not valid.
// program-fixed.ts
var x: string = "1";
var y: number;
console.log(typeof x, typeof y);
x = "hello";
y = 2;
console.log(typeof x, typeof y);
x = "true";
y = 3;
console.log(typeof x, typeof y);
// string, undefined
// string, number
// string, number
Once we fix all the issues, TypeScript will generate the output file program-fixed.js
that is safe to run wherever we want. TypeScript keeps the original filename of the source file and only replaces the extension.
// program-fixed.js
var x = "1";
var y;
console.log(typeof x, typeof y);
x = "hello";
y = 2;
console.log(typeof x, typeof y);
x = "true";
y = 3;
console.log(typeof x, typeof y);
// string, undefined
// string, number
// string, number
As you can see from the above output, things in the output program have not changed a bit. So what was the point? Where did all the type annotations go?
If the type annotations leaked in the compiled output, it wouldn’t be a valid JavaScript program since the JavaScript engine doesn’t understand what type annotations are and it would throw SyntaxError as shown below.
What TypeScript adopts is an Erased Type System that removes type annotations any type related information from the compiled program. The type annotations are only there to provide type information of values to the TypeScript compiler during the compilation process. Therefore TypeScript also falls in the category of statically typed languages.
The goal of TypeScript is to catch mistakes in a program before it goes to production and causes problems at the runtime. Its goal is not to provide tools to amend or modify the original source code (business logic) such that can it perform well at the runtime in all the situations.
However, being the superset of JavaScript, it is its moral responsibility to support existing standards of JavaScript such as ES2020
which is the current one. But a developer can mistakenly use a feature from a standard that is pretty new such as Promise
from ES6
and run the compiled program in an environment that doesn’t support Promises such as IE11
(_which only supports JavaScript features up until _ES5
).
This is solved by TypeScript using a configuration file, mainly named tsconfig.json
, that contains information about the project and what is expected from the TypeScript compiler. This is a plain JSON file.
{
"files": ["./program.ts"],
"compilerOptions": {
"outDir": "./dist",
"target": "ES5",
"module": "CommonJS"
}
}
The outDir
specifies the directory where the output .js
files should be emitted by the compiler. The target
option specifies the JavaScript version that will be supported by the runtime and module
option specifies the module system available at the runtime such as CommonJS
used by the Node.js.
When you run the tsc
command, the TypeScript compiler looks for the tsconfig.json
in the current directory. You can provide a custom file path of this configuration file using using --project
or -p
command-line flag.
Since the target
in this case is set to ES5
, you would get a compilation error if you use any JavaScript feature that is not the part of ES5
specifications such as Promise
. However, some features are compiled to target
version such as let
variable declaration is converted to var
declaration.
So it is safe to say that TypeScript will inform about most of the situations at the compile time that could possible cause issues at the runtime. Now we can clearly see why TypeScript is ❤️ (loved) by JavaScript developers.
💡 According to Wikipedia, TypeScript first appeared in October 2012 and the first stable version v0.8 was released to the public in the same month. This could mean that Microsoft took the idea or at least the motivation from Dart but nevertheless, it turned out to be a great f***ng decision.
More about TypeScript
TypeScript compiler is written in JavaScript, as crazy as it sounds, that’s a 100% true fact. However, the original source code of this compiler is written in TypeScript. Therefore TypeScript is self-hosted.
TypeScript is open-source and its official project repository is hosted on Github (link here). The src
directory contains the source code of the TypeScript compiler along with other programs.
The lib
directory contains the type definitions for JavaScript APIs (_such as _Promise
) and browser APIs (such as fetch
) that is used by the TypeScript compiler to validate your code if these APIs are used in your code. The bin
directory contains all the command-line tools.
TypeScript has one of the best online documentation. You should spend some time reading this documentation from typescriptlang.org. TypeScript provides an online REPL to compile and test TypeScript programs online.
What to expect from this article series?
In this article series, we will discuss almost all the features TypeScript has to offer with some cool examples. You can find the source of these examples from this GitHub repository (work in progress).
- Introduction: First, we will discuss about the structure of a TypeScript program and how to compile it using the
tsc
orts-node
and run it. Then we will discuss the basic data types provided by the TypeScript such asstring
,number
, etc. - Complex Data Types: Then we will discuss the complex data types such as
functions
,classes
as well as custom data types such asinterfaces
andenums
provided by the TypeScript. - Type System: TypeScript is entirely based on types. That’s why it is necessary to understand the Type System employed by the TypeScript. We will talk about this through various lessons on Type System specifications, Generics, Polymorphism, Data Immutability, and Utility Types.
- New Features: TypeScript being the superset of JavaScript supports the new features of ECMAScript standard. Therefore we will talk about these features in this section such as Promises using Async/Await, Decorators, etc.
- Module System: Module System is a hot topic in the JavaScript world at the moment. ES6 introduced support for modules natively and it is getting better day by day. In this section, we will talk about the module system and related topics.
- Compilation: This is where TypeScript ends, the compilation of TypeScript programs, the final frontier of TypeScript developers. In this section, we are going to discuss the configuration file
tsconfig.json
, the TypeScript compiler, and command-line API.
💡 These articles will be presented to you in the sequential order under the
TypeScript
tag in the menu of this publication.
I am almost done with all the articles but I would rather release them one or two in a week so that they are properly edited for grammatical and programmatical errors.
💡 I would recommend you to subscribe to this publication to receive these articles in your feed. I do not earn a single penny from these articles so a clap or follow is much appreciated.