Buch „Professionelles TypeScript. Skalierbare JavaScript-Anwendungen entwickeln "

BildJeder Programmierer, der mit einer dynamisch typisierten Sprache arbeitet, wird bestätigen, dass die Skalierung von Code unglaublich schwierig ist und ein großes Team von Ingenieuren erfordert. Aus diesem Grund haben Facebook, Google und Microsoft eine statische Eingabe für dynamisch eingegebenen Code entwickelt.



In jeder Programmiersprache verfolgen wir Ausnahmen und lesen den Code Zeile für Zeile, um das Problem zu finden und zu beheben. Mit TypeScript können Sie diesen frustrierenden Teil des Entwicklungsprozesses automatisieren.



TypeScript ist im Gegensatz zu vielen anderen typisierten Sprachen anwendungsorientiert. Es werden neue Konzepte vorgestellt, mit denen Sie Ideen prägnanter und genauer ausdrücken und auf einfache Weise skalierbare und sichere moderne Anwendungen erstellen können.



Boris Cherny hilft Ihnen, alle Nuancen und Funktionen von TypeScript zu verstehen, und zeigt Ihnen, wie Sie Fehler beseitigen und den Code skalieren können.



Buchstruktur



Ich (der Autor) habe versucht, Ihnen ein theoretisches Verständnis der Funktionsweise von TypeScript und eine ganze Reihe praktischer Codierungshinweise zu vermitteln.



TypeScript ist eine praktische Sprache, daher ergänzen sich Theorie und Praxis im Buch meistens, aber die ersten beiden Kapitel behandeln hauptsächlich die Theorie, und gegen Ende wird nur die Praxis vorgestellt.



Wir werden die Grundlagen wie den Compiler, die Typprüfung und die Typen selbst behandeln. Als nächstes diskutieren wir ihre Varianten und Operatoren und gehen dann zu fortgeschrittenen Themen über, wie z. B. Besonderheiten des Typsystems, Fehlerbehandlung und asynchrone Programmierung. Abschließend zeige ich Ihnen, wie Sie TypeScript mit Ihren bevorzugten Frameworks (Frontend und Backend) verwenden, ein vorhandenes JavaScript-Projekt nach TypeScript migrieren und eine TypeScript-Anwendung in der Produktion ausführen.



Die meisten Kapitel enden mit einer Reihe von Ăśbungen. Versuchen Sie, sie selbst zu machen, um das Material besser zu verstehen. Antworten darauf finden Sie hier .



Stufenweise Migration von JavaScript zu TypeScript



TypeScript wurde unter Berücksichtigung der JavaScript-Interoperabilität entwickelt. Die Migration zu TypeScript ist zwar nicht ganz schmerzlos, macht aber dennoch Spaß. Sie können Ihre Codebasisdatei gleichzeitig transformieren, ein höheres Maß an Sicherheit und Commit nach Commit erhalten und Ihren Chef und Ihre Mitarbeiter überraschen, wie leistungsfähig statisch typisierter Code sein kann. ...



Auf hoher Ebene sollte die Codebasis vollständig in TypeScript geschrieben und stark typisiert sein, und die JavaScript-Bibliotheken von Drittanbietern, auf die Sie angewiesen sind, sollten von guter Qualität sein und ihre eigenen starken Typen haben. Der Codierungsprozess wird durch das Abfangen von Fehlern beim Kompilieren und das umfangreiche TypeScript-Autocomplete-System verdoppelt. Um ein erfolgreiches Migrationsergebnis zu erzielen, sind einige kleine Schritte erforderlich:



  • FĂĽgen Sie dem Projekt TSC hinzu.
  • ĂśberprĂĽfen Sie die Typen des vorhandenen JavaScript-Codes.
  • Verschieben Sie JavaScript-Code Datei fĂĽr Datei in TypeScript.
  • Installieren Sie Typdeklarationen fĂĽr Abhängigkeiten. Weisen Sie also Typen fĂĽr Abhängigkeiten zu, die sie nicht haben, oder schreiben Sie Typdeklarationen fĂĽr nicht typisierte Abhängigkeiten und senden Sie sie an DefinitelyTyped1 zurĂĽck.
  • Aktivieren Sie den strengen Modus fĂĽr die Codebasis.


Dieser Vorgang kann eine Weile dauern, aber Sie werden später sofort die Sicherheits- und Leistungssteigerungen und andere Vorteile sehen. Werfen wir einen Blick auf die aufgeführten Schritte.



Schritt 1: HinzufĂĽgen von TSC



Wenn Sie mit einer Codebasis arbeiten, die TypeScript und JavaScript kombiniert, lassen Sie TSC zuerst die JavaScript-Dateien zusammen mit den TypeScript-Dateien in den Einstellungen von tsconfig.json kompilieren:



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


Allein diese Änderung ermöglicht es TSC, JavaScript-Code zu kompilieren. Fügen Sie einfach TSC zum Erstellungsprozess hinzu und führen Sie entweder jede JavaScript-Datei durch oder führen Sie weiterhin ältere JavaScript-Dateien durch den Erstellungsprozess und neue TypeScript-Dateien über TSC aus.



Wenn allowJs auf true gesetzt ist, ĂĽberprĂĽft TypeScript keine Typen im aktuellen JavaScript-Code, sondern transpiliert diesen Code mit dem von Ihnen angeforderten Modulsystem (im Modulfeld) in ES3, ES5 oder die Version, die in der Datei tsconfig.json als Ziel festgelegt ist JSON-Datei). Der erste Schritt ist abgeschlossen. Legen Sie es fest und klopfen Sie sich auf den RĂĽcken - Ihre Codebasis verwendet jetzt TypeScript.



Schritt 2a: Aktivieren Sie die JavaScript-TypprĂĽfung (optional).



Nachdem TSC JavaScript verarbeitet, können Sie die Typen überprüfen. Auch wenn keine expliziten Typanmerkungen vorhanden sind, denken Sie daran, dass TypeScript Typen für JavaScript-Code auf dieselbe Weise wie für TypeScript-Code ableiten kann. Fügen Sie die erforderliche Option in tsconfig.json ein:



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


Wenn TypeScript nun eine JavaScript-Datei kompiliert, wird versucht, Typen auf die gleiche Weise wie fĂĽr TypeScript-Code abzuleiten und zu validieren.



Wenn Ihre Codebasis groß ist und beim Aktivieren von checkJs zu viele Fehler gleichzeitig auftreten, deaktivieren Sie sie. Aktivieren Sie stattdessen die JavaScript-Dateiprüfung nacheinander, indem Sie die Anweisung // @ ts-check hinzufügen (ein normaler Kommentar oben in der Datei). Wenn große Dateien eine Reihe von Fehlern verursachen, die Sie noch nicht beheben möchten, lassen Sie checkJs aktiviert und fügen Sie die Anweisung // @ ts-nocheck für diese Dateien hinzu.



TypeScript kann nicht für alles Typen ableiten (z. B. nicht Typen für Funktionsparameter), daher werden viele Typen in JavaScript als solche abgeleitet. Wenn Sie den strengen Modus in tsconfig.json aktiviert haben (empfohlen), ziehen Sie es möglicherweise vor, implizite Modi während der Migration zuzulassen. Fügen Sie tsconfig.json Folgendes hinzu:



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


Denken Sie daran, noImplicitAny erneut zu aktivieren, wenn Sie den GroĂźteil Ihres Codes nach TypeScript migriert haben. Wenn Sie dies tun, werden Sie wahrscheinlich viele verpasste Fehler finden (es sei denn, Sie sind Zenidar, ein SchĂĽler der JavaScript-Hexe Bavmorda, der mit einem Wermuttrank mit der Kraft seines geistigen Auges tippen kann).


Wenn TypeScript JavaScript-Code ausführt, wird ein weicherer Inferenzalgorithmus als TypeScript-Code verwendet. Nämlich:



  • Alle Funktionsparameter sind optional.
  • Die Arten von Eigenschaften von Funktionen und Klassen werden basierend auf ihrer Verwendung abgeleitet (anstatt im Voraus deklariert werden zu mĂĽssen):



    class A {
        x = 0 // number | string | string[],    .
         method() {
                 this.x = 'foo'
         }
         otherMethod() {
                 this.x = ['array', 'of', 'strings']
         }
    
    }
  • Nachdem Sie ein Objekt, eine Klasse oder eine Funktion deklariert haben, können Sie ihr zusätzliche Eigenschaften zuweisen. Hinter den Kulissen generiert TypeScript dazu einen geeigneten Namespace fĂĽr jede Funktionsdeklaration und fĂĽgt jedem Objektliteral automatisch eine Indexsignatur hinzu.


Schritt 2b: JSDoc-Anmerkungen hinzufĂĽgen (optional)



Möglicherweise sind Sie in Eile und müssen nur eine Typanmerkung für eine neue Funktion hinzufügen, die einer alten JavaScript-Datei hinzugefügt wurde. Sie können dazu die JSDoc-Annotation verwenden, bis Sie diese Datei in TypeScript konvertieren können.



Sie haben JSDoc wahrscheinlich schon einmal gesehen. Dies sind Kommentare wie diese oben im Code mit Anmerkungen, die mit @ beginnen, wie zparam, @returns usw. TypeScript versteht JSDoc und verwendet es zusammen mit expliziten Typanmerkungen als Eingabe fĂĽr die TypprĂĽfung.



Angenommen, Sie haben eine 3000-Zeilen-Servicedatei (ja, ich weiĂź, Ihr "Freund" hat sie geschrieben). Sie fĂĽgen eine neue Servicefunktion hinzu:



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


Ohne eine vollständige Konvertierung von utils.js in TypeScript, die sicherlich eine Reihe von Fehlern aufdeckt, können Sie nur die Funktion toPascaleCase mit Anmerkungen versehen, wodurch eine kleine Sicherheitsinsel im Meer von untypisiertem JavaScript entsteht:



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


Ohne diese Annotation wĂĽrde JSDoc TypeScript den toPascaleCase-Typ als (word: any) => string ableiten. Beim Kompilieren wird nun bekannt, dass der toPascaleCase-Typ (word: string) => string ist. Und Sie erhalten nĂĽtzliche Unterlagen.



Weitere Informationen zu JSDoc-Anmerkungen finden Sie im TypeScript-Wiki (https://github.com/Microsoft/TypeScript/wiki/JSDoc-support-in-JavaScript).



Schritt 3: Benennen Sie die Dateien in .ts um



Sobald Sie Ihrem Erstellungsprozess TSC hinzugefĂĽgt und optional mit der ĂśberprĂĽfung von Typen und dem Kommentieren von JavaScript-Code begonnen haben, ist es an der Zeit, zu TypeScript zu wechseln.



Aktualisieren Sie Datei für Datei die Dateiberechtigungen von .js (oder .coffee, es6 usw.) auf .ts. Unmittelbar nach dem Umbenennen von Dateien im Editor werden rot gewellte Freunde angezeigt, die auf Typfehler, fehlende Fälle, vergessene Nullprüfungen und Tippfehler in Variablennamen hinweisen. Es gibt zwei Möglichkeiten, sie zu entfernen.



  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 {
       // ...
}


Beide Ansätze sind sehr relevant, und es liegt an Ihnen, zu entscheiden, welcher vorzuziehen ist. TypeScript ist eine schrittweise typisierte Sprache, die von Grund auf so konzipiert wurde, dass sie auf möglichst sichere Weise mit untypisiertem JavaScript interagiert. Es spielt keine Rolle, ob Sie mit untypisiertem JavaScript oder schwach typisiertem TypeScript interagieren. Stark typisiertes TypeScript stellt immer sicher, dass die Interaktion so sicher wie möglich ist.



Schritt 4: Aktivieren Sie die Genauigkeit



Sobald eine kritische Masse an JavaScript-Code portiert wurde, möchten Sie die All-in-One-Sicherheit erhöhen, indem Sie die strengeren TSC-Flags einzeln verwenden (eine vollständige Liste der Flags finden Sie in Anhang E).



Wenn Sie fertig sind, können Sie die TSC-Flags deaktivieren, die für die Interaktion mit JavaScript verantwortlich sind, und bestätigen, dass Ihr gesamter Code in stark typisiertem TypeScript geschrieben ist:



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


Dadurch werden alle verbleibenden Typfehler angezeigt. Repariere sie und erhalte eine fehlerfreie, sichere Codebasis, fĂĽr die die meisten Hardcore-Ingenieure von OCaml dir auf den RĂĽcken klopfen wĂĽrden.

Wenn Sie diese Schritte ausführen, können Sie beim Hinzufügen von Typen zum von Ihnen gesteuerten JavaScript-Code weit kommen. Aber was ist mit Codes, die nicht von Ihnen gesteuert werden? Wie die mit NPM installierten. Aber bevor wir diese Frage untersuchen, lassen Sie uns ein wenig abschweifen ...



Suchen von Typen fĂĽr JavaScript



Wenn Sie eine JavaScript-Datei aus einer TypeScript-Datei importieren, sucht TypeScript mithilfe des folgenden Algorithmus nach Typdeklarationen (denken Sie daran, dass in TypeScript „Datei“ und „Modul“ synonym verwendet werden):



  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"]
     }
}




Beim Importieren eines JavaScript-Moduls eines Drittanbieters (des NPM-Pakets, das Sie in Knotenmodulen installiert haben) verwendet TypeScript einen etwas anderen Algorithmus:



  1. Sucht nach einer lokalen Typdeklaration fĂĽr das Modul und verwendet sie, falls vorhanden.



    Zum Beispiel sieht Ihre Verzeichnisstruktur folgendermaĂźen aus:



    my-app /

    ├──node_modules /

    │ ffoo /

    ├──src /

    │ indeindex.ts

    │ typtypes.d.ts



    So sieht type.d aus .ts:



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


    Wenn Sie dann foo importieren, verwendet TypeScript die externe Moduldeklaration in types.d.ts als Typquelle dafĂĽr:



    // index.ts

    Importleiste aus 'foo'
  2. package.json, . types typings, .d.ts, , .
  3. Oder es durchsucht die Verzeichnisse nach dem Verzeichnis node modules / @ types, das die Typdeklarationen für das Modul enthält.



    Zum Beispiel haben Sie React installiert:



    npm install react --save

    npm install @ types / react --save-dev



    my-app /

    ├──node_modules /

    │ ├── @ types /

    │ │ └─react /

    │ └── react /

    ├──src /

    │ └index.ts



    Beim Importieren von React findet TypeScript das Verzeichnis @ types / react und verwendet es als Quelle fĂĽr Typdeklarationen:



    // index.ts

    import * als React from 'react'
  4. Andernfalls werden die Schritte 1 bis 3 des Suchalgorithmus fĂĽr den lokalen Typ ausgefĂĽhrt.


Ich habe einige Schritte aufgelistet, aber Sie werden sich daran gewöhnen.



Ăśber den Autor



Boris Cherny ist Chefingenieur und Produktführer bei Facebook. Zuvor arbeitete er bei VC, AdTech und in verschiedenen Startups, von denen die meisten heute nicht mehr existieren. Er interessiert sich für Programmiersprachen, Codesynthese und statische Analyse und bemüht sich, seine Erfahrungen mit digitalen Produkten mit Benutzern zu teilen. In seiner Freizeit organisiert er TypeScript-Clubtreffen in San Francisco und unterhält einen persönlichen Blog - performancejs.com . Sie finden Boris 'GitHub-Account unter github.com/bcherny .



»Weitere Details zum Buch finden Sie auf der Website des Herausgebers.

» Inhaltsverzeichnis

» Auszug



fĂĽr Habitaner 25% Rabatt auf den Gutschein - TypeScript



Nach Zahlungseingang fĂĽr die Papierversion des Buches wird ein E-Book an die E-Mail gesendet.



All Articles