Comprendre Typescript en 5 minutes

En dehors du titre, le générique masculin est utilisé sans aucune discrimination et uniquement dans le but d'alléger le texte.

Comprendre Typescript en 5 minutes

Typescript a explosé en popularité en 2019 et continue sa folle course en 2020. Le premier langage qui tape le top 10 en moins de 5 ans. Incroyable. Incroyable qu’on ait toujours pas discuté de cette affaire.



Il était une fois

Nous sommes en 2010. Anders Hejlsberg, le concepteur du framework .NET, en a plein le cul de Javascript. Il bosse chez Microsoft. Chez Microsoft, et chez les clients externes de Microsoft, tout le monde est d’accord sur un point. Le Javascript n’est pas fait pour les projets à grandes échelles.

Mais Javascript est quand même utilisé dans ces projets de grande envergure. Ces projets sont en Javascript pour une raison simple : les navigateurs n’acceptent que le Javascript ! Tout le monde est bloqué avec.

C’est avec ce problème en tête que Microsoft va commencer à bosser sur Typescript. Le projet va être développé pendant deux ans en interne.

En octobre 2012, la version 0.8 de Typescript passe publique pour la première fois. Beaucoup de développeurs vont alors immédiatement changer de religion.



typescript


Et même si les premiers adorateurs sont plus qu’intenses, les premières années de Typescript seront discrètes. Le temps pour Typescript de se faire connaitre et de prendre ces marques. À partir de 2017, ça commence à être la folie côté adoption. Et la suite de l’histoire, t’en as sûrement déjà entendu parler non ?



pull requests


C’est quoi Typescript ?

Typescript est un langage de programmation open source fait par Microsoft. Pour être plus précis, c’est un surensemble de Javascript. C’est-à-dire que tout programme Javascript existant est déjà un programme Typescript valide. Autrement dit, si t’es un développeur Javascript, t’as aucune barrière d’entrée.

Typescript est un langage multi paradigmes. Tu peux faire du fonctionnel, comme de l’orienté objet sans problème. Et je te parle de vrai orienté objet, pas d’orienté objet via prototype comme en Javascript. La combinaison POO et le fait que Typescript soit un langage fortement typé a tout changé.

En fait, Typescript explose en popularité grâce aux développeurs qui viennent de langages comme Java et C++. Ces développeurs ont horreur de Javascript à cause de sa nature interprétée, beaucoup trop permissive. Typescript leur permet de faire du Javascript, donc de travailler dans le navigateur, en gardant leur environnement fortement typé et orienté objet. Et beaucoup d’entre eux voient Typescript comme un tueur de Javascript



typescript


Alors, c’est évidemment pas le cas puisqu’en réalité Typescript va générer du Javascript en permanence. Typescript ne fait que transcompiler du code en Javascript. Et je dis bien transcompiler, non pas compiler, car c’est différent. Ce fonctionnement est perturbant ? OK, voyons comment ça marche cette affaire.



Comment ça marche ?

Typescript, c’est très simple. Enfin, c’est simple pour nous, les utilisateurs. Microsoft a dû s’arracher les cheveux à faire ça.

D’abord tu vas développer en Typescript dans des fichiers .ts. Ça ressemble comme deux gouttes d’eau à Javascript, tu vas pas être perdu. La différence c’est que tu seras dans un environnement objet et fortement typé (de façon optionnelle toujours).

Typescript vient avec un compilateur (TSC). Ce compilateur, c’est vraiment ça qui fait que Typescript c’est un truc de fifou. Pendant le développement c’est ce compilateur qui va transcompiler ton application Typescrit en application Javascript. OK, dessin !



compilateur


Le truc important à comprendre c’est que la partie Typescript c’est la partie développement dans un environnement typé, “sécurisé”, fait pour attraper les bugs. Après transcompilation, on est en Javascript. C’est la partie interprétation au runtime et donc plus exposé aux bugs.

Mais comme on est passé par Typescript avant, notre application est “renforcée”. Et c’est ça qui fait le succès de Typescript. On a assez discuté théorie, mettons les mains dedans.



Fais voir le code

Je pars du principe que tu es sur une sainte distrib Linux et les exemples ici tournent tous sur du Node 13. Commençons par installer cette affaire. On va utiliser npm, l’installer de façon générale et vérifier que l’installation s’est bien faite.

npm install -g typescript
tsc --version

Débutons par un truc quotidien dans ton Javascript de tous les jours. Un simple async/await. On va appeler une fonction async via un await et on va simuler une latence de 1 sec avec un setTimeout et une promesse. Pour le moment, on reste en format Javascript et ça donne ça.

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)

Je t’ai dit plus haut que tout code Javascript et un code Typescript valide. Donc on devrait pouvoir transcompiler ce code non ? Lançons le compilateur dans le même dossier pour voir.

tsc

Ce qui va générer un fichier async.js qui ressemble à ça.

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];
            }
        });
    });
}

Et là tu vas me dire : c’est quoi cet enfer ? D’où sort tout ce code infernal ? C’est quoi ce bordel ? Je préfère mourir que bosser avec un truc pareil. Et je te comprends.

Mais en fait, c’est juste qu’on n’a pas configuré notre compilateur. Alors du coup, il fait n’importe quoi. Par défaut, il va partir du principe que tu veux du Javascript compatible ES3. Une très ancienne spécification. Une époque ou async/await n’existait pas. Il essaye de reproduire async/await comme si on était en 1999.



typescript


Pour éviter cette torture pour les yeux, configurons cette affaire. Pour ce faire, comme toujours, direction la doc. On va créer un fichier tsconfig.json à la racine. Ça va être notre config.

{
  "compilerOptions": {
    "target": "esnext",
    "watch": true
  }
}

Target : c’est la cible de compilation Javascript. Il faut mettre la spécification ECMAScript que tu veux. Y’a pas longtemps je t’ai parler de l’ES2020 alors mettons la dernière spécification via “esnext”.

Watch : ça veut dire que le compilateur va transcompiler ton code si ton fichier change. Semblable à un nodemon en NodeJS. En relançant TSC, le code généré est identique et le compilateur attend tout changement.

Très bien, maintenant regardons un exemple plus évolué. On va faire ce que Javascript ne sais pas faire. Utilisation de vraie interface (sans duck typing), de typage fort et le tout dans un environnement objet.



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);


Je crée une classe Hero avec un constructeur. L’utilisation du public dans les arguments du constructeur me permet de créer automatiquement une propriété name. Puis, toujours dans la classe Hero, je déclare age (typé number) et powers (typé array de string).

Derrière, je crée une interface qui établit un contrat name, age, powers. Ensuite, une fonction qui prend en argument mon interface. Enfin, un bout de code qui va appeler ma classe pour afficher le JSON.

Et ça fonctionne ! Essaye de passer un string pour l’age, de pas mettre de name à l’instanciation de la classe ou d’enlever une propriété dans la classe. Typescript va hurler et te laissera pas transcompiler en Javascript.



Épilogue

Ça fait plus de cinq minutes qu’on discute, je m’arrête là. Tu trouveras plus d’exemples de code par ici. Je trouve cette technologie vraiment parfaite pour des projets de grande envergure. Un layer de protection pareille au développement est rassurant. J’espère t’avoir donné envie de tester tout ça par toi-même !

Qui me parle ?

jesuisundev
Je suis un dev. En ce moment je suis Backend Développeur / DevOps à Montréal. Le dev est l'une de mes passions et j'écris comme je parle. Je continue à te parler quotidiennement sur mon Twitter. Tu peux m'insulter à cet e-mail ou le faire directement dans les commentaires juste en dessous. Y'a même une newsletter !

17 commentaires sur “Comprendre Typescript en 5 minutes”

  1. Hello,
    Merci pour tes articles chaque lundi matin.
    Pour celui-ci, je vois une petite erreur dans ton code: à la ligne 14, tu passes un argument appelé “anonym” alors qu’aux lignes 16-18, tu utilises une variable “person” qui n’est pas définie.

    Merci pour tes articles et continue comme ça!

  2. Personnellement j’ai toujours vu Typescript comme un langage pour les développeurs Java qui ont la flemme d’apprendre à développer en JS.

    1. J’ai le même point de vue, pour moi c’est un langage pour les anciens développeurs back-end qu’on a dû recycler pour faire du front-end.

  3. Perso Typescript m’a empéché de me pendre quand j’ai commencer à dév quelques gros projets JS. Quand tu fais du kikoo jquery sur 3 pages d’un site osef , mais sur les gros projets quel plaisir. Rajoute à ca que je passe mes journées à sauter de C++ à Java à PHP qui n’utilisent évidemment pas de prototype … ca facilite tellement les choses ! Comble du bonheur , je peux copier une enum class c++ quasi directement en TS et ca c’est trop cool 😀

  4. Je suis assez d’accord avec @Nico.
    Vouloir transposer des paradigmes d’un autre langage en râlant parce que ce n’est pas possible dans un autre, c’est juste parce que t’as la flemme d’apprendre.
    Y’a des trucs mieux que d’autres en JS, bien entendu, mais pour paraphraser Crockford, ceux qui critiquent l’héritage prototypal du JS c’est juste qu’ils ont pas appris/compris le langage.
    D’autres diront que de toute façon la POO c’est de la merde et que y’a que le fonctionnel de vrai… bref.
    Ce que je trouve de positif, c’est que chacun puisse y trouver son compte !

    1. “Vouloir transposer des paradigmes d’un autre langage en râlant parce que ce n’est pas possible dans un autre, c’est juste parce que t’as la flemme d’apprendre.”

      En partie oui, en partie non.
      Il faut aussi prendre en compte qu’il y a des dizaines et des dizaines de langages en activité (cad pas un truc de micro niche) et il arrive un moment où il n’est plus possible de tirer partie des particularismes de chacun. Meme si ce sont justement les particularismes qui font toute la valeur…
      Donc la tendance est déjà d’abrasé ce qui pourrait différer au niveau de la syntaxe pour retrouver la syntaxe habituelle du C/C++/Java/C# afin de préserver le reste des fonctionalitées. On peut le regretter mais c’est ce qui permet de faciliter l’adoption d’un nouveau langage. Il suffit de voir l’exemple d’Erlang qui par sa syntaxe trop différente s’est tiré une balle dans le pied. Alors qu’il avait de gros avantages.

      Il faut aussi prendre en compte que tout le monde ne peut pas passer tous les soirs 4h à apprendre le nouveau langage hype du moment. Quand je dis apprendre je dis vraiment connaitre, pas seulement survoler deux tutos.

  5. Hello, merci pour tes articles qui me permettent d’avoir des aperçus rapide de sujets qui me sont totalement inconnus. Est-ce que tu pourrais me préciser ce que tu entends par “Un layer de protection pareille au développement est rassurant.” ?

  6. Très bon article ! J’ai commencé à faire du Typescript il y a environ 2/3 ans surtout sur de gros projets. Ça fait du bien de retrouver le paradigme objet et le typage fort dans un environnement JavaScript (surtout quand on vient du C++ comme moi ou d’un autre langage orienté objet).

    Après j’avoue que sur mes projets perso je n’utilise que très rarement du Typescript, j’ai toujours l’impression d’être bridé avec et perdre une certaine flexibilité que j’ai avec le JavaScript.

    Par contre, comme tu l’a dit derrière c’est du JavaScript qui est généré , je conseille donc à tous les développeurs Typescript (mais aussi aux développeurs JavaScript) de bien comprendre comment fonctionne JavaScript et surtout l’héritage par prototype. C’est hyper important, je pense, de savoir ce qui se cache derrière le mot clé “class”. On peut-être amené a utiliser des librairies ou récupérer du code legacy qui utilise le “prototype” ça évitera de se demander ce que fait ce code “bizarre”. Soyez curieux 😉 !

    PS: merci pour le lien sur le duck typing 😉

  7. Salut
    Un petit bémol: les graphes se basant sur Github sont tout sauf représentatifs. Car la population de Github n’est pas répresentative de l’ensemble du monde du développement (développeurs, CTOs, entreprises, etc). Mais c’est pratique pour voir apparaître des tendances (ce que montre très bien le graphe de l’article).

    Cela peut s’expliquer par le fait que beaucoup de projet Github sont des “pet projects” pour se faire la main sur un nouveau langage.
    Il y avait quelques année j’avais lu un article qui décrivait ca comme le syndrome de la calculatrice.

    Chaque fois qu’un nouveau langage ou framework/lib apparait tout le monde veut se faire la main dessus et pour faire un premier test écrit… une calculatrice. Résultat à chaque fois des dizaines et des dizaines de calculatrice apparaissent sur les depots & app store. Mais une fois cette calculatrice finie beaucoup de gens passent à autre chose – une autre calculatrice ^^’ – et ne font pas d’autres applications qui, elles, enrichissent le nouvel eco système…

  8. Bon la vérité, je comprends le besoin et l’objectif de typescript mais quand je lit que le js ne convient pas à un gros projet, j’arrive toujours pas à comprendre pourquoi ? J’ai l’impression de toujours me répété mais aujourd’hui t’as de fortes chance de chier du js dans un framework (Vue, React etc..), et dedans tu as souvent des toolkits de vérifications des proptypes. Donc je vois pas pourquoi est-ce que juste le js ne serait pas assez solide ? surtout si tu suis bien le fonctionnement des try/catch avec cette surcouche de proptypes vérifiés.
    Je suis peut-être un peu trop fermé sur mon language de fronteux, mais effectivement je rejoins ce que d’autres disent, le typescript c’est un peu le langage pour calmer les frustrations des devs venant d’autres langages fortement typés..

  9. Hello, super article comme à ton habitude ! 🙂

    Petite question un peu naïve au sujet de ton dernier exemple, je n’ai vu personne le mentionner dans les commentaires… (je suis développeur C#, et j’ai une méconnaissance en Javascript, je précise :p)
    Pourquoi au niveau de ta classe Hero tu ne fais pas un “class Hero implements Anonym” exactement ?

    Merci d’avance pour éclairer ma lanterne ! 🙂

T'en penses quoi ?

Your email address will not be published. Required fields are marked *