Pouvez-vous décrire ce qu'est le langage TypeScript ?
Que peut-il faire que JavaScript ou les bibliothèques disponibles ne peuvent pas faire, qui me donnerait une raison de l'envisager ?
Pour vous faire une idée de ce que je veux dire, regardez [la vidéo d'introduction de Microsoft][2] sur le langage.
Pour un projet JavaScript de grande envergure, l'adoption de TypeScript pourrait se traduire par un logiciel plus robuste, tout en restant déployable là où une application JavaScript ordinaire s'exécuterait.
Il s'agit d'un langage open source, mais vous ne bénéficiez de l'astucieux Intellisense lors de la saisie que si vous utilisez un IDE pris en charge. Au départ, il s'agissait uniquement de Visual Studio de Microsoft (voir également le billet de blog de [Miguel de Icaza][3]). Aujourd'hui, [d'autres IDE prennent également en charge TypeScript][4].
A titre d'exemple, voici un peu de TypeScript (vous pouvez jouer avec dans le [TypeScript Playground][9])
class Greeter {
greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
Et voici le JavaScript qu'il produirait
var Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();
Remarquez comment le TypeScript définit le type des variables membres et des paramètres des méthodes de classe. Ces informations sont supprimées lors de la traduction en JavaScript, mais sont utilisées par l'IDE et le compilateur pour repérer les erreurs, comme le passage d'un type numérique au constructeur.
Il est également capable de déduire des types qui ne sont pas explicitement déclarés, par exemple, il pourrait déterminer que la méthode greet()
renvoie une chaîne de caractères.
[1] : http://www.typescriptlang.org [2] : http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript [3] : http://tirania.org/blog/archive/2012/Oct-01.html [4] : https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support [5] : http://coffeescript.org/ [6] : http://www.hanselman.com/blog/WhyDoesTypeScriptHaveToBeTheAnswerToAnything.aspx [7] : http://en.wikipedia.org/wiki/Dart_%28programming_language%29 [8] : http://www.dartlang.org/docs/dart-up-and-running/contents/ch04-tools-dart2js.html [9] : http://www.typescriptlang.org/Playground/ [10] : https://stackoverflow.com/questions/12711826/debugging-typescript-code-with-visual-studio
TypeScript est un surensemble typé de JavaScript qui se compile en JavaScript ordinaire. JavaScript - [typescriptlang.org][1]. JavaScript est un langage de programmation développé par le [Comité technique 39 de l'EMCA][2], qui est un groupe de personnes composé de nombreuses parties prenantes différentes. Le TC39 est un comité hébergé par [ECMA][3] : un organisme de normalisation interne. JavaScript fait l'objet de nombreuses implémentations différentes par de nombreux fournisseurs différents (par exemple Google, Microsoft, Oracle, etc.). L'objectif de JavaScript est d'être la lingua franca du web. TypeScript est un surensemble du langage JavaScript qui possède un seul compilateur open-source et est développé principalement par un seul fournisseur : Microsoft. L'objectif de TypeScript est d'aider à détecter rapidement les erreurs grâce à un système de types et de rendre le développement JavaScript plus efficace. Essentiellement, TypeScript atteint ses objectifs de trois façons :
- Prise en charge des fonctionnalités JavaScript modernes - Le langage JavaScript (pas le moteur d'exécution) est normalisé par les normes [ECMAScript][4]. Tous les navigateurs et les moteurs d'exécution JavaScript ne prennent pas en charge toutes les fonctionnalités de toutes les normes ECMAScript (voir cet [aperçu][5]). TypeScript permet l'utilisation de la plupart des dernières fonctionnalités ECMAScript et les traduit en cibles ECMAScript plus anciennes de votre choix (voir la liste des [cibles de compilation][6] sous l'option de compilation
--target
). Cela signifie que vous pouvez utiliser en toute sécurité les nouvelles fonctionnalités, comme les modules, les fonctions lambda, les classes, l'opérateur d'étalement et la déstructuration, tout en restant rétrocompatible avec les navigateurs et les moteurs d'exécution JavaScript plus anciens.- Système de types avancé - Le support des types ne fait pas partie de la norme ECMAScript et ne le sera probablement jamais en raison de la nature interprétée plutôt que compilée de JavaScript. Le système de types de TypeScript est incroyablement riche et comprend : interfaces, enums, types hybrides, génériques, types d'union/intersection, modificateurs d'accès et bien plus encore. Le [site officiel][1] de TypeScript donne un aperçu de ces fonctionnalités. Le système de types de TypeScript est comparable à celui de la plupart des autres langages typés, voire plus puissant dans certains cas.
- Support d'outils pour les développeurs - Le compilateur de TypeScript peut s'exécuter en tant que processus d'arrière-plan pour prendre en charge à la fois la compilation incrémentale et l'intégration IDE, de sorte que vous pouvez plus facilement naviguer, identifier les problèmes, inspecter les possibilités et remanier votre base de code.
La relation de TypeScript avec les autres langages de ciblage JavaScript
TypeScript a une philosophie unique par rapport aux autres langages qui compilent vers JavaScript. Le code JavaScript est du code TypeScript valide ; TypeScript est un superset de JavaScript. Vous pouvez presque renommer vos fichiers
.js
en fichiers.ts
et commencer à utiliser TypeScript (voir "Interopérabilité JavaScript" ci-dessous). Les fichiers TypeScript sont compilés en JavaScript lisible, de sorte que la migration en arrière est possible et la compréhension du TypeScript compilé n'est pas difficile du tout. TypeScript s'appuie sur les succès de JavaScript tout en améliorant ses faiblesses. D'une part, vous disposez d'outils à l'épreuve du temps qui prennent les normes ECMAScript modernes et les compilent vers des versions JavaScript plus anciennes, Babel étant le plus populaire. D'autre part, vous avez des langages totalement différents de JavaScript qui ciblent JavaScript, comme CoffeeScript, Clojure, Dart, Elm, Haxe, Scala.js et bien d'autres (voir cette [liste][7]). Ces langages, bien qu'ils puissent être meilleurs que ce à quoi l'avenir de JavaScript pourrait mener, courent un plus grand risque de ne pas être suffisamment adoptés pour que leur avenir soit garanti. Vous pourriez également avoir plus de difficultés à trouver des développeurs expérimentés pour certains de ces langages, bien que ceux que vous trouverez soient souvent plus enthousiastes. L'interopérabilité avec JavaScript peut également être un peu plus complexe, car ces langages sont plus éloignés de ce qu'est réellement JavaScript. TypeScript se situe entre ces deux extrêmes, équilibrant ainsi le risque. TypeScript n'est en aucun cas un choix risqué. Il faut très peu d'efforts pour s'y habituer si vous êtes familier avec JavaScript, puisqu'il ne s'agit pas d'un langage complètement différent, qu'il bénéficie d'une excellente interopérabilité avec JavaScript et qu'il a été beaucoup adopté récemment.Typage statique facultatif et inférence de type
JavaScript est typée dynamiquement. Cela signifie que JavaScript ne connaît pas le type d'une variable avant qu'elle ne soit effectivement instanciée au moment de l'exécution. Cela signifie également qu'il peut être trop tard. TypeScript ajoute le support des types à JavaScript. Les bogues causés par de fausses suppositions sur le fait qu'une variable est d'un certain type peuvent être complètement éradiqués si vous jouez vos cartes correctement (la rigueur avec laquelle vous tapez votre code ou si vous tapez votre code du tout dépend de vous). TypeScript rend le typage un peu plus facile et beaucoup moins explicite par l'utilisation de l'inférence de type. Par exemple :
var x = "hello"
en TypeScript est la même chose quevar x : string = "hello"
. Le type est simplement déduit de son utilisation. Même si vous ne tapez pas explicitement les types, ils sont toujours là pour vous éviter de faire quelque chose qui, autrement, entraînerait une erreur d'exécution. TypeScript est optionnellement typé par défaut. Par exemple,fonction divideByTwo(x) { return x / 2 }
est une fonction valide en TypeScript qui peut être appelée avec tout type de paramètre, même si l'appeler avec une chaîne de caractères entraînera évidemment une erreur d'exécution. Tout comme vous êtes habitués à le faire en JavaScript. Cela fonctionne, parce que lorsque aucun type n'a été explicitement assigné et que le type ne pouvait pas être déduit, comme dans l'exemple de divideByTwo, TypeScript assignera implicitement le typeany
. Cela signifie que la signature de type de la fonction divideByTwo devient automatiquementfonction divideByTwo(x : any) : any
. Il existe un drapeau de compilation pour interdire ce comportement :--noImplicitAny
. Activer ce flag vous donne un plus grand degré de sécurité, mais signifie aussi que vous devrez faire plus de typage. Les types ont un coût qui leur est associé. Tout d'abord, il y a une courbe d'apprentissage, et ensuite, bien sûr, cela vous coûtera un peu plus de temps pour mettre en place une base de code utilisant un typage strict approprié. D'après mon expérience, ces coûts en valent totalement la peine pour toute base de code sérieuse que vous partagez avec d'autres. Le document [A Large Scale Study of Programming Languages and Code Quality in Github][8] suggère que "les langages typés statiquement, en général, sont moins sujets aux défauts que les types dynamiques, et que le typage fort est meilleur que le typage faible à cet égard". Il est intéressant de noter que ce même article constate que TypeScript est moins sujet aux erreurs que JavaScript : Pour ceux qui ont des coefficients positifs, nous pouvons nous attendre à ce que le langage Pour ceux qui ont des coefficients positifs, nous pouvons nous attendre à ce que le langage soit associé, ceteris paribus, à un plus grand nombre de corrections de défauts. Ces langages incluent C, C++, JavaScript, Objective-C, Php, et > Python. Python. Les langages Clojure, Haskell, Ruby, Scala et TypeScript*, ont tous des coefficients négatifs, ce qui implique que ces langages sont moins sont moins susceptibles que la moyenne de donner lieu à des commits de correction de défauts.Support IDE amélioré
L'expérience de développement avec TypeScript est une grande amélioration par rapport à JavaScript. L'IDE est informé en temps réel par le compilateur TypeScript sur ses riches informations de type. Cela donne quelques avantages majeurs. Par exemple, avec TypeScript, vous pouvez effectuer en toute sécurité des refactorings tels que des renommages sur l'ensemble de votre base de code. Grâce à la complétion de code, vous pouvez obtenir une aide en ligne sur toutes les fonctions qu'une bibliothèque peut offrir. Plus besoin de les mémoriser ou de les rechercher dans des références en ligne. Les erreurs de compilation sont signalées directement dans l'EDI par une ligne rouge ondulée pendant que vous êtes en train de coder. Au final, cela permet un gain de productivité important par rapport au travail en JavaScript. On peut passer plus de temps à coder et moins de temps à déboguer. Il existe un large éventail d'IDE qui offrent une excellente prise en charge de TypeScript, comme Visual Studio Code, WebStorm, Atom et Sublime.
Vérifications strictes des nullités
Les erreurs d'exécution de la forme
cannot read property 'x' of undefined
ouundefined is not a function
sont très souvent causées par des bugs dans le code JavaScript. D'emblée, TypeScript réduit déjà la probabilité que ces types d'erreurs se produisent, puisqu'on ne peut pas utiliser une variable qui n'est pas connue du compilateur TypeScript (à l'exception des propriétés des variables typéestous
). Il est cependant toujours possible d'utiliser par erreur une variable qui est définie commeundefined
. Cependant, avec la version 2.0 de TypeScript, vous pouvez éliminer ce genre d'erreurs grâce à l'utilisation de types non-nullables. Cela fonctionne comme suit : Avec les contrôles stricts de nullité activés (drapeau de compilation--strictNullChecks
) le compilateur TypeScript ne permettra pasundefined
d'être assigné à une variable à moins que vous ne la déclariez explicitement comme étant de type nullable. Par exemple,let x : nombre = indéfini
entraînera une erreur de compilation. Cela correspond parfaitement à la théorie des types puisqueundefined
n'est pas un nombre. On peut définirx
comme étant un type somme denumber
etundefined
pour corriger cela :let x : nombre | indéfini = indéfini
. Une fois qu'un type est connu pour être nullable, ce qui signifie qu'il est d'un type qui peut également être de la valeurnull
ouundefined
, le compilateur TypeScript peut déterminer par une analyse de type basée sur le flux de contrôle si votre code peut utiliser une variable en toute sécurité ou non. En d'autres termes, lorsque vous vérifiez qu'une variable estundefined
à travers par exemple une instructionif
, le compilateur TypeScript en déduira que le type dans cette branche du flux de contrôle de votre code n'est plus nullable et peut donc être utilisé en toute sécurité. Voici un exemple simple :
let x: number | undefined;
if (x !== undefined) x += 1; // this line will compile, because x is checked.
x += 1; // this line will fail compilation, because x might be undefined.
Lors de la conférence build, 2016, le co-concepteur de TypeScript Anders Hejlsberg a donné une explication détaillée et une démonstration de cette fonctionnalité : [vidéo][9] (de 44:30 à 56:30).
Pour utiliser TypeScript, vous avez besoin d'un processus de construction pour compiler le code JavaScript. Le processus de compilation ne prend généralement que quelques secondes, en fonction bien sûr de la taille de votre projet. Le compilateur TypeScript prend en charge la compilation incrémentale (drapeau de compilateur --watch
) afin que toutes les modifications ultérieures puissent être compilées plus rapidement.
Le compilateur TypeScript peut intégrer des informations de carte source dans les fichiers .js générés ou créer des fichiers .map séparés. Les informations de carte source peuvent être utilisées par des utilitaires de débogage tels que Chrome DevTools et d'autres IDE pour relier les lignes du JavaScript à celles qui les ont générées dans TypeScript. Cela vous permet de définir des points d'arrêt et d'inspecter les variables pendant l'exécution directement sur votre code TypeScript. Les informations de la carte source fonctionnent assez bien, elles existaient bien avant TypeScript, mais le débogage de TypeScript n'est généralement pas aussi bon que lorsqu'on utilise directement JavaScript. Prenez le mot-clé this
par exemple. En raison du changement de sémantique du mot-clé this
autour des fermetures depuis ES2015, this
peut en fait exister pendant l'exécution comme une variable appelée _this
(voir cette réponse). Cela peut vous perturber lors du débogage, mais ce n'est généralement pas un problème si vous le savez ou si vous inspectez le code JavaScript. Il est à noter que Babel souffre exactement du même genre de problème.
Il existe quelques autres astuces que le compilateur TypeScript peut réaliser, comme générer du code d'interception basé sur les décorateurs, générer du code de chargement de module pour différents systèmes de modules et analyser [JSX][12]. Cependant, vous aurez probablement besoin d'un outil de construction autre que le compilateur Typescript. Par exemple, si vous souhaitez compresser votre code, vous devrez ajouter d'autres outils à votre processus de compilation pour y parvenir.
Il existe des plugins de compilation TypeScript disponibles pour [Webpack][13], [Gulp][14], [Grunt][15] et à peu près tous les autres outils de compilation JavaScript. La documentation de TypeScript contient une section sur [l'intégration avec les outils de compilation][16] qui les couvre tous. Un [linter][17] est également disponible au cas où vous souhaiteriez vérifier encore plus le temps de construction. Il existe également un grand nombre de projets d'amorçage qui vous permettront de commencer à utiliser TypeScript en combinaison avec un grand nombre d'autres technologies comme Angular 2, React, Ember, SystemJS, Webpack, Gulp, etc.
Puisque TypeScript est si étroitement lié à JavaScript, il a de grandes capacités d'interopérabilité, mais un travail supplémentaire est nécessaire pour travailler avec les bibliothèques JavaScript dans TypeScript. Les [définitions TypeScript][18] sont nécessaires pour que le compilateur TypeScript comprenne que les appels de fonctions comme _.groupBy
ou angular.copy
ou $.fadeOut
ne sont pas en fait des déclarations illégales. Les définitions de ces fonctions sont placées dans des fichiers .d.ts
.
La forme la plus simple que peut prendre une définition est de permettre à un identifiant d'être utilisé de n'importe quelle façon. Par exemple, en utilisant [Lodash][19], un fichier de définition d'une seule ligne declare var _ : any
vous permettra d'appeler n'importe quelle fonction que vous voulez sur _
, mais bien sûr, vous pourrez toujours faire des erreurs : _.foobar()
sera un appel TypeScript légal, mais sera, bien sûr, un appel illégal au moment de l'exécution. Si vous voulez un support de type et une complétion de code appropriés, votre fichier de définition doit être plus précis (voir [lodash definitions][20] pour un exemple).
Les modules [Npm][21] qui sont livrés pré-packagés avec leurs propres définitions de type sont automatiquement compris par le compilateur TypeScript (voir [documentation][22]). Pour presque toutes les autres bibliothèques JavaScript semi-populaires qui n'incluent pas leurs propres définitions, quelqu'un a déjà rendu les définitions de type disponibles par le biais d'un autre module npm. Ces modules sont préfixés par "@types/" et proviennent d'un dépôt Github appelé [DefinitelyTyped][23].
Il y a une mise en garde : les définitions de type doivent correspondre à la version de la bibliothèque que vous utilisez au moment de l'exécution. Si ce n'est pas le cas, TypeScript pourrait vous empêcher d'appeler une fonction ou de déréférencer une variable qui existe ou vous permettre d'appeler une fonction ou de déréférencer une variable qui n'existe pas, simplement parce que les types ne correspondent pas à la version d'exécution au moment de la compilation. Assurez-vous donc de charger la bonne version des définitions de types pour la bonne version de la bibliothèque que vous utilisez.
Pour être honnête, il y a un léger inconvénient à cela et c'est peut-être l'une des raisons pour lesquelles vous ne choisissez pas TypeScript, mais plutôt quelque chose comme Babel qui ne souffre pas du tout de devoir obtenir des définitions de type. D'un autre côté, si vous savez ce que vous faites, vous pouvez facilement surmonter tout type de problème causé par des fichiers de définition incorrects ou manquants.
Tout fichier .js
peut être renommé en fichier .ts
et passé au compilateur TypeScript pour obtenir en sortie le même code JavaScript syntaxiquement correct (s'il était syntaxiquement correct en premier lieu). Même si le compilateur TypeScript obtient des erreurs de compilation, il produira toujours un fichier .js
. Il peut même accepter les fichiers .js
en entrée avec le drapeau --allowJs
. Cela vous permet de commencer à utiliser TypeScript immédiatement. Malheureusement, des erreurs de compilation sont susceptibles de se produire au début. Il faut se rappeler que ce ne sont pas des erreurs flagrantes comme celles auxquelles vous pouvez être habitué avec d'autres compilateurs.
Les erreurs de compilation que l'on rencontre au début de la conversion d'un projet JavaScript en un projet TypeScript sont inévitables de par la nature de TypeScript. TypeScript vérifie la validité de tout le code et doit donc connaître toutes les fonctions et variables utilisées. Ainsi, les définitions de type doivent être en place pour chacun d'entre eux, sinon des erreurs de compilation sont inévitables. Comme mentionné dans le chapitre ci-dessus, pour presque tous les frameworks JavaScript, il existe des fichiers .d.ts
qui peuvent être facilement obtenus avec l'installation des [paquets DefinitelyTyped][23]. Il se peut cependant que vous ayez utilisé une bibliothèque obscure pour laquelle aucune définition TypeScript n'est disponible ou que vous ayez polyfillé certaines primitives JavaScript. Dans ce cas, vous devez fournir des définitions de type pour ces bits pour que les erreurs de compilation disparaissent. Créez simplement un fichier .d.ts
et incluez-le dans le tableau files
de tsconfig.json, afin qu'il soit toujours pris en compte par le compilateur TypeScript. Dans ce fichier, déclarez les bits que TypeScript ne connaît pas comme type any
. Une fois que vous avez éliminé toutes les erreurs, vous pouvez progressivement introduire le typage dans ces parties en fonction de vos besoins.
Un peu de travail sur la (re)configuration de votre pipeline de construction sera également nécessaire pour obtenir TypeScript dans le pipeline de construction. Comme mentionné dans le chapitre sur la compilation, il y a beaucoup de bonnes ressources disponibles et je vous encourage à chercher des projets d'amorçage qui utilisent la combinaison d'outils avec laquelle vous voulez travailler.
Le plus gros obstacle est la courbe d'apprentissage. Je vous encourage à jouer avec un petit projet au début. Regardez comment il fonctionne, comment il se construit, quels fichiers il utilise, comment il est configuré, comment il fonctionne dans votre IDE, comment il est structuré, quels outils il utilise, etc. Convertir une grande base de code JavaScript en TypeScript est faisable lorsque vous savez ce que vous faites. Lisez ce blog pour voir comment [convertir 600 000 lignes en TypeScript en 72 heures][24]). Assurez-vous simplement d'avoir une bonne maîtrise du langage avant de faire le saut.
TypeScript est open-source (licence Apache 2, voir [GitHub][25]) et soutenu par Microsoft. [Anders Hejlsberg][26], l'architecte principal de C#, est le fer de lance du projet. Il s'agit d'un projet très actif ; l'équipe TypeScript a publié de nombreuses nouvelles fonctionnalités au cours des dernières années et de nombreuses autres sont encore prévues (voir la [feuille de route][27]). Quelques faits concernant l'adoption et la popularité :
"[TypeScript Fundamentals][1]" -- un cours vidéo Pluralsight par [Dan Wahlin][2] et [John Papa][3] est une très bonne, actuellement (25 mars 2016) mise à jour pour refléter TypeScript 1.8, introduction à Typescript.
Pour moi, les caractéristiques les plus intéressantes, outre les possibilités d'intellisense, sont les classes, interfaces, modules, la facilité d'implémentation d'AMD et la possibilité d'utiliser le débogueur Visual Studio Typescript lorsqu'il est invoqué avec IE.
Pour résumer : S'il est utilisé comme prévu, Typescript peut rendre la programmation JavaScript plus fiable et plus facile. Il peut augmenter la productivité du programmeur JavaScript de manière significative sur l'ensemble du SDLC.
[1] : https://www.pluralsight.com/courses/typescript [2] : https://www.pluralsight.com/authors/dan-wahlin [3] : https://www.pluralsight.com/authors/john-papa