Livre «Professional TypeScript. Développement d'applications JavaScript évolutives "

imageTout programmeur travaillant avec un langage typé dynamiquement attestera que la tâche de mise à l'échelle du code est incroyablement difficile et nécessite une grande équipe d'ingénieurs. C'est pourquoi Facebook, Google et Microsoft ont mis au point un typage statique pour le code typé dynamiquement.



Travaillant avec n'importe quel langage de programmation, nous suivons les exceptions et lisons le code ligne par ligne pour trouver le problème et comment le résoudre. TypeScript vous permet d'automatiser cette partie frustrante du processus de développement.



TypeScript, contrairement à de nombreux autres langages typés, est orienté application. Il introduit de nouveaux concepts qui vous permettent d'exprimer des idées de manière plus succincte et précise, et de créer facilement des applications modernes évolutives et sécurisées.



Boris Cherny vous aide à comprendre toutes les nuances et capacités de TypeScript, vous apprend à éliminer les erreurs et à mettre à l'échelle le code.



Structure du livre



J'ai (l'auteur) essayé de vous donner une compréhension théorique du fonctionnement de TypeScript et une bonne quantité de conseils de codage pratiques.



TypeScript est un langage pratique, donc la théorie et la pratique se complètent principalement dans le livre, mais les deux premiers chapitres couvrent principalement la théorie, et vers la fin, seule la pratique est présentée.



Nous couvrirons les bases comme le compilateur, le vérificateur de type et les types eux-mêmes. Ensuite, nous discuterons de leurs variétés et de leurs opérateurs, puis passerons à des sujets avancés tels que les spécificités du système de types, la gestion des erreurs et la programmation asynchrone. Enfin, je vais vous montrer comment utiliser TypeScript avec vos frameworks préférés (frontend et backend), migrer un projet JavaScript existant vers TypeScript et exécuter une application TypeScript en production.



La plupart des chapitres se terminent par une série d'exercices. Essayez-les vous-même pour mieux appréhender le matériau. Les réponses à ces questions sont disponibles ici .



Migration par Ă©tapes de JavaScript vers TypeScript



TypeScript a été conçu avec à l'esprit l'interopérabilité JavaScript. Ainsi, même si ce n'est pas complètement indolore, la migration vers TypeScript est toujours une expérience agréable, vous permettant de transformer votre fichier de base de code à la fois, d'obtenir un niveau de sécurité plus profond et de vous engager après la validation, et de surprendre votre patron et vos collègues à quel point le code de type statique peut être puissant. ...



À un niveau élevé, la base de code doit être entièrement écrite en TypeScript et fortement typée, et les bibliothèques JavaScript tierces dont vous dépendez doivent être de bonne qualité et avoir leurs propres types forts. Votre processus de codage sera jusqu'à 2 fois plus rapide avec la détection des erreurs au moment de la compilation et un système de saisie semi-automatique TypeScript riche. Pour obtenir un résultat de migration réussi, il faudra quelques petites étapes:



  • Ajoutez TSC au projet.
  • Commencez Ă  vĂ©rifier les types de code JavaScript existant.
  • DĂ©placez le code JavaScript vers un fichier TypeScript par fichier.
  • Installez les dĂ©clarations de type pour les dĂ©pendances. Autrement dit, allouez des types pour les dĂ©pendances qui n'en ont pas, ou Ă©crivez des dĂ©clarations de type pour les dĂ©pendances non typĂ©es et renvoyez-les Ă  DefinitelyTyped1.
  • Activez le mode strict pour la base de code.


Ce processus peut prendre un certain temps, mais vous verrez immédiatement des gains de sécurité et de performances et d'autres avantages plus tard. Jetons un coup d'œil aux étapes répertoriées.



Étape 1: ajouter TSC



Lorsque vous travaillez avec une base de code qui combine TypeScript et JavaScript, laissez d'abord TSC compiler les fichiers JavaScript avec les fichiers TypeScript dans les paramètres tsconfig.json:



{
     "compilerOptions": {
     "allowJs": true
}


Ce seul changement permettra à TSC d'être utilisé pour compiler du code JavaScript. Ajoutez simplement TSC au processus de construction et exécutez chaque fichier JavaScript via celui-ci ou continuez à exécuter les fichiers JavaScript hérités via le processus de construction et les nouveaux fichiers TypeScript via TSC.



Avec allowJs défini sur true, TypeScript ne vérifie pas le type du code JavaScript actuel, mais transpile ce code vers ES3, ES5 ou la version définie comme cible dans le fichier tsconfig.json à l'aide du système de module que vous avez demandé (dans le module json). La première étape est terminée. Validez-le et tapotez-vous dans le dos - votre base de code utilise maintenant TypeScript.



Étape 2a: activer la vérification du type JavaScript (facultatif)



Maintenant que TSC traite JavaScript, pourquoi ne pas vérifier ses types? Même s'il n'y a pas d'annotations de type explicite, rappelez-vous que TypeScript peut déduire des types pour le code JavaScript de la même manière que pour le code TypeScript. Incluez l'option requise dans tsconfig.json:



{
     "compilerOptions": {
     "allowJs": true,
     "checkJs": true
}


Désormais, chaque fois que TypeScript compile un fichier JavaScript, il essaiera d'inférer et de valider les types de la même manière qu'il le fait pour le code TypeScript.



Si votre base de code est volumineuse et que vous activez checkJs, elle rencontre trop d'erreurs à la fois, désactivez-la. Au lieu de cela, activez la vérification du fichier JavaScript un par un en ajoutant la directive // ​​@ ts-check (un commentaire normal en haut du fichier). Ou, si les fichiers volumineux génèrent un tas d'erreurs que vous ne voulez pas encore corriger, laissez checkJs activé et ajoutez la directive // ​​@ ts-nocheck pour ces fichiers.



TypeScript ne peut pas déduire de types pour tout (par exemple, il n'infère pas de types pour les paramètres de fonction), il en déduira donc de nombreux types dans JavaScript comme n'importe quel. Si vous avez activé le mode strict dans tsconfig.json (recommandé), vous préférerez peut-être en autoriser implicitement pendant la migration. Ajoutez ce qui suit à tsconfig.json:



{
     "compilerOptions": {
     "allowJs": true,
     "checkJs": true,
     "noImplicitAny": false
}


N'oubliez pas de réactiver noImplicitAny lorsque vous avez terminé la migration de la majeure partie de votre code vers TypeScript. Cela trouvera probablement de nombreux bugs manqués (à moins que vous ne soyez Zenidar, un disciple de la sorcière JavaScript Bavmorda, qui peut vérifier le type avec la puissance de l'œil de son esprit avec une potion d'absinthe).


Lorsque TypeScript exécute du code JavaScript, il utilise un algorithme d'inférence plus doux que le code TypeScript. À savoir:



  • Tous les paramètres de fonction sont facultatifs.
  • Les types de propriĂ©tĂ©s des fonctions et des classes sont dĂ©duits en fonction de leur utilisation (au lieu de devoir ĂŞtre dĂ©clarĂ©s Ă  l'avance):



    class A {
        x = 0 // number | string | string[],    .
         method() {
                 this.x = 'foo'
         }
         otherMethod() {
                 this.x = ['array', 'of', 'strings']
         }
    
    }
  • Après avoir dĂ©clarĂ© un objet, une classe ou une fonction, vous pouvez leur attribuer des propriĂ©tĂ©s supplĂ©mentaires. Dans les coulisses, TypeScript le fait en gĂ©nĂ©rant un espace de noms appropriĂ© pour chaque dĂ©claration de fonction et en ajoutant automatiquement une signature d'index Ă  chaque littĂ©ral d'objet.


Étape 2b: ajouter des annotations JSDoc (facultatif)



Vous êtes peut-être pressé et n'avez qu'à ajouter une annotation de type pour une nouvelle fonction qui a été ajoutée à un ancien fichier JavaScript. Vous pouvez utiliser l'annotation JSDoc pour ce faire jusqu'à ce que vous puissiez convertir ce fichier en TypeScript.



Vous avez probablement déjà vu JSDoc. Ce sont des commentaires comme celui-ci en haut du code avec des annotations commençant par @, commeparam, @returns, etc. TypeScript comprend JSDoc et l'utilise comme entrée du vérificateur de type avec des annotations de type explicites.



Supposons que vous ayez un fichier de service de 3000 lignes (oui, je sais, votre "ami" l'a Ă©crit). Vous y ajoutez une nouvelle fonction de service:



export function toPascalCase(word) {
       return word.replace(
             /\w+/g,
             ([a, ...b]) => a.toUpperCase() + b.join('').toLowerCase()
       )
}


Sans une conversion complète de utils.js en TypeScript, qui révélera sûrement un tas de bogues, vous ne pouvez annoter que la fonction toPascaleCase, créant ainsi un petit îlot de sécurité dans une mer de JavaScript non typé:



/**
     * @param word {string}    .
     * @returns {string}   PascalCase
     */
export function toPascalCase(word) {
     return word.replace(
           /\w+/g,
           ([a, ...b]) => a.toUpperCase() + b.join('').toLowerCase()
     )
}


Sans cette annotation, JSDoc TypeScript inférerait le type toPascaleCase comme (word: any) => string. Maintenant, lors de la compilation, il saura que le type toPascaleCase est (word: string) => string. Et vous obtenez une documentation utile.



Pour plus d'informations sur les annotations JSDoc, visitez le Wiki TypeScript (https://github.com/Microsoft/TypeScript/wiki/JSDoc-support-in-JavaScript).



Étape 3: Renommez les fichiers en .ts



Une fois que vous avez ajouté TSC à votre processus de construction et commencé éventuellement à vérifier les types et à annoter le code JavaScript dans la mesure du possible, il est temps de passer à TypeScript.



Fichier par fichier mettre à jour les autorisations de fichiers de .js (ou .coffee, es6, etc.) vers .ts. Immédiatement après avoir renommé les fichiers dans l'éditeur, vous verrez apparaître des amis ondulés rouges indiquant des erreurs de type, des cas manqués, des vérifications nulles oubliées et des fautes de frappe dans les noms de variables. Il existe deux façons de les supprimer.



  1. . , , , . checkJs, noImplicitAny tsconfig.json, any , , JavaScript .
  2. .ts tsconfig.json ( strict false), . any, . . , strict (noImplicitAny, noImplicitThis, strictNullChecks . .), . ( .)


, TODO any any, . , :



// globals.ts
type TODO_FROM_JS_TO_TS_MIGRATION = any

// MyMigratedUtil.ts
export function mergeWidgets(
       widget1: TODO_FROM_JS_TO_TS_MIGRATION,
       widget2: TODO_FROM_JS_TO_TS_MIGRATION
): number {
       // ...
}


Les deux approches sont tout à fait pertinentes, et c'est à vous de décider laquelle est préférable. TypeScript est un langage typé étape par étape qui est conçu dès le départ pour interagir avec du JavaScript non typé de la manière la plus sécurisée possible. Peu importe que vous interagissiez avec du JavaScript non typé ou du TypeScript faiblement typé, TypeScript fortement typé s'assurera toujours que l'interaction est aussi sûre que possible.



Étape 4: activer la rigueur



Une fois qu'une masse critique de code JavaScript a été portée, vous voulez la sécuriser tout-en-un en utilisant un par un les indicateurs TSC plus stricts (voir l'annexe E pour une liste complète des indicateurs).



Lorsque vous avez terminé, vous pouvez désactiver les indicateurs TSC responsables de l'interaction avec JavaScript, confirmant que tout votre code est écrit en TypeScript fortement typé:



{
     "compilerOptions": {
     "allowJs": false,
     "checkJs": false
}


Cela exposera toutes les erreurs de type restantes. Corrigez-les et obtenez une base de code sans faille et sécurisée que la plupart des ingénieurs acharnés d'OCaml vous féliciteraient.

Suivre ces étapes vous aidera à aller loin lors de l'ajout de types au code JavaScript que vous contrôlez. Mais qu'en est-il des codes qui ne sont pas contrôlés par vous? Comme ceux installés avec NPM. Mais avant d'étudier cette question, faisons une petite digression ...



Recherche de types pour JavaScript



Lorsque vous importez un fichier JavaScript à partir d'un fichier TypeScript, TypeScript recherche les déclarations de type pour celui-ci à l'aide de l'algorithme suivant (rappelez-vous, dans TypeScript, «fichier» et «module» sont utilisés de manière interchangeable):



  1. .d.ts , .js. .js.

    , :



    my-app/

    ├──src/

    │ ├──index.ts

    │ └──legacy/

    │ ├──old-file.js

    │ └──old-file.d.ts



    old-file ( ) index.ts:



    // index.ts

    import './legacy/old-file'



    TypeScript src/legacy/old-file.d.ts ./legacy/old-file.
  2. , allowJs checkJs true, .js ( JSDoc) any.




TSC-: TYPEROOTS ( )



TypeScript node modules/@types , (../node modules/@types . .). .



, typeRoots tsconfig.json , . , TypeScript typings node modules/@types:



{
     "compilerOptions": {
            "typeRoots" : ["./typings", "./node modules/@types"]
     }
}


types tsconfig.json, , TypeScript . , , React:



{
     "compilerOptions": {
             "types" : ["react"]
     }
}




Lors de l'importation d'un module JavaScript tiers (le package NPM que vous avez installé dans les modules de nœuds), TypeScript utilise un algorithme légèrement différent:



  1. Recherche une déclaration de type local pour le module et, s'il en existe une, l'utilise.



    Par exemple, la structure de votre répertoire ressemble à ceci:



    my-app /

    ├──node_modules /

    │ └──foo /

    ├──src /

    │ ├──index.ts

    │ └──types.d.ts



    Voici Ă  quoi ressemble type.d .ts:



    // types.d.ts
    declare module 'foo' {
          let bar: {}
          export default bar
    }


    Si vous importez ensuite foo, TypeScript utilise la déclaration de module externe dans types.d.ts comme source de type:



    // index.ts

    import bar from 'foo'
  2. package.json, . types typings, .d.ts, , .
  3. Ou il parcourra les répertoires à la recherche du répertoire modules de noeud / @ types, qui contient les déclarations de type pour le module.



    Par exemple, vous avez installé React:



    npm install react --save

    npm install @ types / react --save-dev



    my-app /

    ├──node_modules /

    │ ├── @ types /

    │ │ └──react /

    │ └──

    react / ├──src /

    │ └──index.ts



    Lors de l'importation de React, TypeScript trouvera le répertoire @ types / react et l'utilisera comme source des déclarations de type pour celui-ci:



    // index.ts

    import * comme React de 'react'
  4. Sinon, il passera aux Ă©tapes 1 Ă  3 de l'algorithme de recherche de type local.


J'ai énuméré pas mal d'étapes, mais vous vous y habituerez.



A propos de l'auteur



Boris Cherny est ingénieur en chef et chef de produit chez Facebook. Auparavant travaillé chez VC, AdTech et dans une variété de startups, dont la plupart n'existent pas aujourd'hui. Il s'intéresse aux langages de programmation, à la synthèse de code et à l'analyse statique, et s'efforce de partager son expérience des produits numériques avec les utilisateurs. Pendant son temps libre, il organise des réunions du club TypeScript à San Francisco et tient un blog personnel - performancejs.com . Vous pouvez trouver le compte GitHub de Boris sur github.com/bcherny .



»Plus de détails sur le livre peuvent être trouvés sur le site de l'éditeur

» Table des matières

» Extrait



For Habitants 25% de réduction sur coupon - TypeScript



Lors du paiement de la version papier du livre, un e-book est envoyé à l'e-mail.



All Articles