JavaScript became one of the most widely used programming languages because the browser made it unavoidable. If you wanted to build interactive web pages, JavaScript was the language you had to use.
That pushed almost every web developer into JavaScript, whether they loved it or not.
At first, that sounds like a success story. But popularity and developer happiness are not the same thing.
JavaScript was not designed like C or C++. It was created by Brendan Eich in 1995 for the Netscape browser in about 10 days. Its original job was simple: add dynamic behavior to web pages.
Other browsers, including Internet Explorer, adopted JavaScript with their own differences. That is why standardization became necessary. The first official ECMAScript version, ES1, was released in 1997.
If you want more JavaScript history, the video above is a good start. Here we will focus on why TypeScript became useful.
JavaScript did not start as a general-purpose programming language. That changed in 2009 when Ryan Dahl created Node.js using Google Chrome’s V8 JavaScript engine. Suddenly JavaScript could run outside the browser.
This is how Node.js became a major platform. JavaScript moved from browser scripting to backend services, tooling, CLIs, build systems, and more.
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 here.
💡 I like how Go (Golang) is also becoming popular despite being a new language. Go is a statically typed language, so it wouldn’t be fair to compare it with JavaScript. I have a dedicated publication just for Go if you wanna learn it.
This shows that JavaScript is heavily used. But does that mean developers always enjoy working with it? Not exactly. JavaScript is flexible and fun, but that flexibility has a cost.
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 is not the real problem. The bigger issue is type safety. JavaScript is dynamically typed, which means many type-related mistakes are discovered only 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 plain JavaScript does not have a type-checking compiler, this kind of mistake can slip through until the code actually runs.
The failure of Dart
Google tried to solve this problem with Dart, a statically typed language that was originally meant to run in the browser and possibly replace JavaScript. The idea was to ship a Dart VM in Chrome and compile Dart to JavaScript for browsers that did not support it.
💡 According to Wikipedia, Dart first appeared in October 2011 and version 1.0 was released in November 2013.
Developers did not accept Dart as a JavaScript replacement. Later, Dart found a stronger home in cross-platform app development through Google’s Flutter framework.
💡 If you want to learn Dart, I have a dedicated publication for it.
The rise of TypeScript
Let’s come back to JavaScript. Is it popular? Absolutely. Is it loved by every developer who has to maintain a large JavaScript codebase? Not always.
According to the same survey, TypeScript was much higher on the “most loved” list than JavaScript. So what is TypeScript, and why did developers adopt it so quickly?
Microsoft took a different approach from Dart. Instead of replacing JavaScript, they extended it. TypeScript adds optional type syntax on top of JavaScript and compiles back to plain JavaScript.
That is why TypeScript is called a superset of JavaScript. In practical terms, TypeScript is JavaScript with optional types.
So what does that type syntax look like?
Normally, you would write a JavaScript program like this.
// 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
In this JavaScript program, we create two variables: x and y. The variable x starts with the value 1, so its runtime type is number. The variable y has no initial value, so its value is undefined.
If we run this in the browser or Node.js, JavaScript does not complain. The type of x changes from number to string, then to boolean. JavaScript allows this because types are evaluated at runtime.
TypeScript adds a compiler that can catch these problems earlier. It is also a transpiler because it outputs JavaScript.
At this point, our program does not tell TypeScript what values are expected. That is where type annotations come in. A type annotation tells TypeScript what type a value should have.
// 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 this 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 here.

TypeScript uses an erased type system. This means type annotations and type-only information are removed from the compiled JavaScript. The annotations exist to help the TypeScript compiler during compilation.
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
The TypeScript compiler runs as JavaScript, but its source code is written in TypeScript. That makes TypeScript 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
tscorts-nodeand 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,classesas well as custom data types such asinterfacesandenumsprovided 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
TypeScripttag 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.


