Typescript exploded in popularity in 2019 and continues its crazy run in 2020. The first language to hit the top 10 in less than 5 years. Unbelievable.
Once upon a time
This is 2010. Anders Hejlsberg, the responsible for the .NET framework, starts to have a lot of problems with Javascript. He works for Microsoft. And at Microsoft, everyone agrees on one thing. Javascript is not made for large-scale projects.
But Javascript is still used in large-scale projects at Microsoft. Why ? For a very simple reason: browsers only accept Javascript! Everyone is stuck with it. This problem in mind, Microsoft started to work on Typescript.
In October 2012, the version 0.8 of Typescript will go public for the first time. Many developers will then immediately change their religion.
And even if the first Typescript worshippers are intense, the first years of Typescript will be discreet. In 2017, the adoption of Typescript go crazy. And the years after, well, you've probably already heard about it.
What's Typescript?
Typescript is an open source programming language made by Microsoft. To be more precise, it is a superset of Javascript. Any existing Javascript program is already a valid Typescript program. In other words, if you're a Javascript developer, you have no entry barrier.
Typescript is a multi-paradigm language. You can do functional and object-oriented programming just like that. And I'm talking about real object-oriented, not object-oriented via prototype like in Javascript. The combination of OOP and the fact that Typescript is a highly typed language is the big thing here.
Typescript exploded in popularity because of developers coming from languages like Java and C++. These developers hate Javascript because of its interpreted nature, which is far too permissive. Typescript allows them to produce Javascript, therefore to work in the browser, while keeping a strongly typed and object oriented environment. Many of them see Typescript like a Javascript killer.
It is obviously not the case since Typescript will generate Javascript permanently. Typescript just transcompiles code into Javascript. And I say transcompile, not compile, because it's different. Okay, let's see how this works.
How does it work?
Typescript is very simple. Well, it's simple for us, the users. Microsoft must have pulled their hair out doing this.
First you're going to develop in .ts files. Typescript looks like Javascript, you're not going to be lost. However, you'll be in an object and strongly typed environment.
Typescript comes with a compiler (TSC). This compiler is really what makes Typescript a fancy thing. During development, this compiler will constantly transcompile your Typescript application into a Javascript application. OK, drawing !
Here's the important thing to understand : the Typescript part of the development is a typed, "secure" environment, made to catch bugs. After transcompilation, we're in Javascript. The interpretation at runtime part and therefore more exposed to bugs.
But as we went through Typescript before, our application is "reinforced". That's also what made Typescript so successful. A more secure way to handle huge codebase in Javascript. Enough theory, let's get our hands on it.
Show me the code
I'm assuming you're on a holy Linux distribution and the examples here are all runing on Node 13. Let's start by installing it. We're going to use npm to install it generally, then check that the installation was done correctly.
npm install -g typescript
tsc --version
Let's start with a daily thing in your everyday Javascript journey. A simple async/await. We'll call an async function via an await and simulate a 1 sec latency with a setTimeout and a promise. Right now, we stay in Javascript format and it looks like this.
async.ts
async function displayUser(idUser) {
try {
const user = await _getUserData(idUser)
console.log(user)
} catch (error) {
console.log(error)
}
}
async function _getUserData(id) {
const user = await new Promise(resolve => setTimeout(() => resolve({ id, name: 'superToto' }), 1000))
return user
}
displayUser(1)
I told you before that any Javascript code is a valid Typescript code. So we should be able to transcompile that code, right? Let's run the compiler in the same folder.
tsc
Which will generate an async.js file that looks like this.
function displayUser(idUser) {
return __awaiter(this, void 0, void 0, function () {
var user, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, _getUserData(idUser)];
case 1:
user = _a.sent();
console.log(user);
return [3 /*break*/, 3\];
case 2:
error_1 = _a.sent();
console.log(error_1);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
}
function _getUserData(id) {
return __awaiter(this, void 0, void 0, function () {
var user;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(function () { return resolve({ id: id, name: 'superToto' }); }, 1000); })];
case 1:
user = _a.sent();
return [2 /*return*/, user];
}
});
});
}
What the hell is this ? Where does all this infernal code come from ? Nobody wants to work with something like this. And nobody should !
But actually, we just haven't configured our compiler. By default, it will assume that you want ES3 compatible Javascript. A very old specification. A time when async/await didn't exist. He's trying to replicate async/await like it's 1999 !
To avoid this torture, let's configure the compiler. To do that, as always, we need the documentation. We need to create a tsconfig.json file at the root. That'll be our config.
{
"compilerOptions": {
"target": "esnext",
"watch": true
}
}
Target: this is the Javascript compilation target. You have to put the ECMAScript specification you want. Let's just put the last specification using "esnext".
Watch: this means that the compiler will transcompile your code if your file changes. Similar to a nodemon with NodeJS. By restarting TSC, the generated code is identical and the compiler is waiting for any changes.
All right, now let's look at a more advanced example. We're going to do what Javascript can't do. Using real interface (no duck typing), strong typing and all this in an object environment.
class Hero {
constructor(public name: String) {}
age: Number;
powers: Array<string>;
}
interface Anonym {
name: string;
age: number;
powers: Array<string>;
}
function displayHeroInfo(anonym: Anonym) {
const heroInfo = {
name: anonym.name,
age: anonym.age,
powers: anonym.powers
}
console.log(heroInfo);
}
const superToto = new Hero("SuperToto");
superToto.age = 25
superToto.powers = ['telekinesis', 'laser']
displayHeroInfo(superToto);
I'm creating a Hero class with a constructor. Using the public in the constructor arguments allows me to automatically create a name property. Then, still in the Hero class, I declare age (typed number) and powers (typed string array).
After that, I create an interface that establishes a contract name, age, powers. Then, a function that takes my interface as an argument. Finally, a piece of code that will call my class to display the JSON.
And it works! Try to pass a string for age, to not put a name at the instantiation of the class or to remove a property in the class. Typescript will scream and won't let you transcompile to Javascript.
Epilogue
We've been talking for more than five minutes. I'm done here. You'll find more sample codes over here. I find this technology really perfect for large-scale projects. A layer of protection like this in development is reassuring. I hope I've made you want to try it out for yourself!
Top comments (2)
Excellent, well explained. Thank you!
Beautifully explained! 👏🏼