TypeScript

Erweitern Sie Ihre JavaScript-Fertigkeiten mit TypeScript

Bill Wagner

Codebeispiel herunterladen

Die TypeScript-Programmiersprache ist eine eigene Obermenge von JavaScript. Wenn Sie JavaScript verwenden, schreiben Sie eigentlich TypeScript. Dies bedeutet jedoch nicht, dass Sie gutes TypeScript schreiben und sich alle Features zunutze machen. Allerdings bedeutet es einen problemlosen Übergang von Ihren existierenden JavaScript-Kenntnissen zu einer TypeScript-Codebasis, die den neuen TypeScript-Funktionsumfang voll ausnutzt.

In diesem Artikel gebe ich Ihnen Empfehlungen für die Migration von Anwendungen von JavaScript zu TypeScript. Sie lernen dabei, wie Sie von JavaScript zu TypeScript wechseln und mit dem TypeScript-Typensystem besseren Code schreiben können. Mit der statischen Analyse von TypeScript können Sie Fehler minimieren und produktiver arbeiten. Mit meinen Empfehlungen können Sie außerdem die Anzahl der Fehler und Warnungen im TypeScript-Typensystem bei der Migration minimieren.

Ich beginne mit einer Beispielanwendung, die ein Adressbuch verwaltet. Es handelt sich um eine Single-Page Application (SPA), die clientseitiges JavaScript verwendet. Zur Vereinfachung enthält dieser Artikel nur den Teil der Anwendung, der eine Liste von Kontakten anzeigt. Die Anwendung verwendet das Angular-Framework für Datenbindung und Anwendungs-Support. Das Angular-Framework ist für Datenbindung und Anzeige der Kontaktinformationen anhand von Vorlagen verantwortlich.

Die Anwendung besteht aus drei JavaScript-Dateien: app.js enthält den Code, der die Anwendung startet. contactsController.js ist der Controller für die Auflistungsseite. contactsData.js enthält eine Liste der anzuzeigenden Kontakte. Der Controller steuert—zusammen mit dem Angular-Framework—das Verhalten der Auflistungsseite. Sie können die Kontakte sortieren und die Details für jeden einzelnen Kontakt ein- oder ausblenden. contactsData.js enthält eine fest codierte Liste von Kontakten. In einer Produktionsanwendung würde diese Datei den Code zum Abrufen von Daten von einem Server enthalten. Die fest codierte Kontaktliste ermöglicht jedoch eine kompaktere Demonstration.

Machen Sie sich keine Sorgen, falls Sie mit Angular nicht vertraut sind. Bei der Migration der Anwendung werden Sie sehen, wie leicht dieses Framework zu verwenden ist. Die Anwendung folgt den Angular-Konventionen, die bei der Migration einer Anwendung zu TypeScript leicht einzuhalten sind.

Der beste Ort, um mit der Migration zu TypeScript zu beginnen, ist die Controller-Datei. Da jeder gültige JavaScript-Code auch gleichzeitig gültiger TypeScript-Code ist, können Sie die Erweiterung der Controller-Datei contactsController.js einfach von .js zu .ts ändern. Die TypeScript-Sprache ist ein Bewohner erster Klasse in Visual Studio 2013 Update 2. Wenn Sie die Web Essentials-Erweiterung installiert haben, sehen Sie sowohl den TypeScript-Quellcode als auch die generierte JavaScript-Ausgabe im gleichen Fenster (siehe Abbildung 1).

The TypeScript Editing Experience in Visual Studio 2013 Update 2
Abbildung 1 Das TypeScript-Editorfenster in Visual Studio 2013 Update 2

Und da die TypeScript-spezifischen Sprachfeatures noch nicht verwendet werden, sind die beiden Ansichten beinahe identisch. Der zusätzliche Kommentar am Ende enthält Informationen zum Debuggen von TypeScript-Anwendungen für Visual Studio. In Visual Studio können Sie Anwendungen auf TypeScript-Ebene debuggen, anstelle der generierten JavaScript-Quellebene.

Sie sehen, dass der TypeScript-Compiler einen Fehler für die Anwendung meldet, obwohl der Compiler eine gültige JavaScript-Ausgabe erzeugt. Dies ist eines der großartigen Features der TypeScript-Sprache. Es ist eine natürliche Folge der Regel, dass TypeScript eine strenge Obermenge von JavaScript ist. Ich habe das Symbol contactsApp noch in keiner TypeScript-Datei deklariert. Daher nimmt der TypeScript-Compiler den Typ any an und geht davon aus, dass dieses Symbol auf ein Objekt zur Laufzeit verweist. Trotz dieser Fehler kann ich die Anwendung ausführen, und sie wird korrekt funktionieren.

Ich könnte nun fortfahren und die Erweiterungen der restlichen JavaScript-Dateien in der Anwendung ändern. Damit sollten Sie jedoch noch warten, da Sie sonst noch viel mehr Fehler angezeigt bekommen. Die Anwendung würde trotzdem funktionieren, aber die vielen Fehler machen es schwerer für das TypeScript-System, Ihnen beim Schreiben von besserem Code zu helfen. Ich bearbeite die Dateien daher normalerweise nacheinander und füge die Typinformationen schrittweise zur Anwendung hinzu. Auf diese Weise zeigt mit das Typensystem eine übersichtlichere Anzahl an Fehlern an. Sobald ich eine fehlerfreie Version habe, weiß ich, dass mir der Compiler beim Vermeiden dieser Fehler hilft.

Sie können eine externe Variable für contactsApp schnell und einfach deklarieren. Standardmäßig hat diese Variable den Typ any:

declare var contactsApp: any;

Dies behebt zwar den Compilerfehler, hilft jedoch nicht bei der Vermeidung von Fehlern beim Aufruf von Methoden in der Angular-Bibliothek. Der Typ any entspricht genau seinem Namen: Er kann alles Mögliche enthalten. TypeScript führt keinerlei Typenprüfung aus, wenn Sie auf die contactsApp-Variable zugreifen. Für die Typenprüfung müssen Sie TypeScript etwas über den Typ von contactsApp und über die im Angular-Framework definierten Typen mitteilen.

TypeScript ermöglicht Typeninformationen für existierende JavaScript-Bibliotheken mit einem Feature namens Typdefinitionen. Eine Typdefinition ist ein Satz von Deklarationen ohne Implementierung. Die beschreiben die Typen und deren APIs für den TypeScript-Compiler. Das DefinitelyTyped-Projekt auf GitHub bietet Typdefinitionen für viele beliebte JavaScript-Bibliotheken an, darunter auch Angular.js. Ich binde diese Definitionen mit dem NuGet-Paket-Manager in das Projekt eingeben.

Sobald ich die Typdefinitionen für die Angular-Bibliothek eingebunden habe, kann ich diese zur Behebung der angezeigten Compilerfehler verwenden. Ich muss auf die neu zum Projekt hinzugefügten Typinformationen verweisen. Ein spezieller Kommentar weist den TypeScript-Compiler an, auf Typinformationen zu verweisen:

/// <reference path="../Scripts/typings/angularjs/angular.d.ts" />

Der TypeScript-Compiler kann nun alle in der Typdefinitionsdatei angular.d.ts definierten Typen interpretieren. Nun können Sie den Typ der contactsApp-Variable korrigieren. Für die in app.js im Namespace ng deklarierte contactsApp-Variable wird der Typ IModule angenommen:

declare var contactsApp: ng.IModule;

Mit dieser Deklaration bekomme ich Hilfe von IntelliSense, wenn ich einen Punkt nach contactsApp eingebe. Außerdem bekomme ich Fehlermeldungen vom TypeScript-Compiler, wenn ich mich vertippe oder die für das contactsApp-Objekt deklarierten APIs falsch verwende. Die Compilerfehler sind verschwunden, und ich habe statische Typinformationen zum Projekt hinzugefügt.

Im Rest des Codes für das contactsController-Objekt fehlen jedoch immer noch Typinformationen. Wenn Sie keine Typanmerkungen hinzufügen, geht der TypeScript-Compiler davon aus, dass alle Variablen vom Typ any sind. Der zweite Parameter der contactsApp.controller-Methode ist eine Funktion. Der erste Parameter dieser Funktion, $scope, ist vom Typ ng.IScope. Ich füge diesen Typen also zur Funktionsdeklaration hinzu (contactData wird weiterhin als any-Typ interpretiert):

contactsApp.controller('ContactsController', function ContactsController($scope : ng.IScope, contactData) { $scope.sortOrder = 'last'; $scope.hideMessage = "Hide Details"; $scope.showMessage = "Show Details"; $scope.contacts = contactData.getContacts(); $scope.toggleShowDetails = function (contact) { contact.showDetails = !contact.showDetails; } });

Nach dieser Änderung werden einige neue Compilerfehler angezeigt. Dies liegt daran, dass der Code in der contactsController-Funktion Eigenschaften verändert, die nicht Teil des Typs ng.IScope sind. Ng.IScope ist eine Schnittstelle, und das eigentliche $scope-Objekt ist ein anwendungsspezifischer Typ, der IScope implementiert. Diese veränderten Eigenschaften sind Teil dieses Typs. Um die statische Typisierung von TypeScript nutzen zu können, muss ich diesen anwendungsspezifischen Typ definieren. Ich nenne ihn IContactsScope:

interface IContactsScope extends ng.IScope { sortOrder: string; hideMessage: string; showMessage: string; contacts: any; toggleShowDetails: (contact: any) => boolean; }

Sobald ich die Schnittstelle definiert habe, kann ich den Typ der $scope-Variable in der Funktionsdeklaration ändern:

function ContactsController($scope : IContactsScope, contactData) {

Mit diesen Änderungen kann ich die Anwendung ohne Fehler erstellen und sie wird korrekt ausgeführt. Beim Hinzufügen dieser Schnittstelle können Sie einige wichtige Konzepte beobachten. Beachten Sie, dass ich keinen weiteren Code suchen oder deklarieren musste, dass irgendein bestimmter Typ den Typ iContactsScope implementiert. TypeScript unterstützt strukturelle Typisierung, umgangssprachlich auch "Duck Typing" genannt. Dies bedeutet, dass jedes Objekt, das die Eigenschaften und Methoden aus iContactsScope deklariert, automatisch auch die iContactsScope-Schnittstelle implementiert, unabhängig davon, ob dies ausdrücklich im jeweiligen Typ angegeben wird.

Beachten Sie, dass ich den TypeScript-Typ any als Platzhalter in der Definition von IContactsScope verwende. Die contacts-Eigenschaft repräsentiert die Liste der Kontakte, und ich habe den Typ Contact noch nicht migriert. Ich kann any als Platzhalter verwenden, und der TypeScript-Compiler wird beim Zugriff auf diese Werte keinerlei Typenprüfung durchführen. Dies ist eine hilfreiche Technik bei der Migration von Anwendungen.

Der Typ any steht für alle Typen, die ich noch nicht von JavaScript nach TypeScript migriert habe. Dieser Trick erleichtert die Migration und minimiert die Fehler im TypeScript-Compiler, die ich in jeder Iteration korrigieren muss. Außerdem kann ich nach Variablen vom Typ any suchen, um meine ausstehenden Aufgaben zu finden. "Any" weist den TypeScript-Compiler an, dass er keine Typenprüfung für diese Variable ausführen soll. Die Variable kann alles Mögliche enthalten. Der Compiler geht davon aus, dass Sie die APIs der jeweiligen Variable kennen. Dies bedeutet nicht, dass Sie "any" nicht verwenden sollten. Dieser Typ macht in verschiedenen Szenarien Sinn, z. B. eine JavaScript-API verschiedene Typen von Objekten verarbeiten kann. Die Verwendung von "any" als Platzhalter bei einer Migration ist nur ein gutes Beispiel.

In der Deklaration von toggleShowDetails sehen Sie außerdem, wie Funktionsdeklarationen in TypeScript dargestellt werden:

toggleShowDetails: (contact: any) => boolean;

Der Funktionsname ist toggleShowDetails. Nach dem Doppelpunkt folgt die Parameterliste. Diese Methode nimmt einen einzelnen Parameter vom Typ any entgegen. Der Name "contact" ist optional. Er dient hauptsächlich dazu, Informationen für andere Programmierer anzugeben. Der Pfeil zeigt auf den Rückgabetyp, in diesem Beispiel vom Typ boolean.

Nachdem Sie den Typ any in der IContactScope-Definition eingeführt haben, gehen Sie nun zum nächsten Schritt über. TypeScript hilft bei der Vermeidung von Fehlern, wenn Sie bestimmte Angaben über die Typen machen, die Sie verwenden. TypeScript ersetzt any durch eine bessere Definition eines Kontakts, indem ein IContact-Typ definiert wird, der die verfügbaren Eigenschaften eines contact-Objekts enthält (siehe Abbildung 2).

Abbildung 2 Eigenschaften eines contact-Objekts

interface IContact { first: string; last: string; address: string; city: string; state: string; zipCode: number; cellPhone: number; homePhone: number; workPhone: number; showDetails: boolean }

Nun kann ich die IContact-Schnittstelle in der IContactScope-Schnittstelle verwenden:

interface IContactsScope extends ng.IScope { sortOrder: string; hideMessage: string; showMessage: string; contacts: IContact[]; toggleShowDetails: (contact: IContact) => boolean; }

Ich muss keine Typinformationen zur Definition der toggleShowDetails-Funktion in der contactsController-Funktion hinzufügen. Da die $scope-Variable vom Typ IContactsScope ist, weiß der TypeScript-Compiler, dass die Funktion toggleShowDetails mit dem in IContactScope definierten Funktions-Prototyp übereinstimmen muss und dass der Parameter ein IContact sein muss.

Abbildung 3 zeigt den generierten JavaScript-Code für diese Version von contactsController. Beachten Sie, dass alle Schnittstellentypen, die ich definiert habe, aus dem generierten JavaScript-Code verschwunden sind. Die Typanmerkungen sind nur für Sie selbst und für statische Analyse-Tools. Diese Anmerkungen werden nicht in den generierten JavaScript-Code übernommen, da sie dort nicht benötigt werden.

Abbildung 3 Die TypeScript-Version des Controllers und der generierte JavaScript-Code

/// reference path="../Scripts/typings/angularjs/angular.d.ts" var contactsApp: ng.IModule; interface IContact { first: string; last: string; address: string; city: string; state: string; zipCode: number; cellPhone: number; homePhone: number; workPhone: number; showDetails: boolean } interface IContactsScope extends ng.IScope { sortOrder: string; hideMessage: string; showMessage: string; contacts: IContact[]; toggleShowDetails: (contact: IContact) => boolean; } contactsApp.controller('ContactsController', function ContactsController($scope : IContactsScope, contactData) { $scope.sortOrder = 'last'; $scope.hideMessage = "Hide Details"; $scope.showMessage = "Show Details"; $scope.contacts = contactData.getContacts(); $scope.toggleShowDetails = function (contact) { contact.showDetails = !contact.showDetails; return contact.showDetails; } }); // Generated JavaScript /// reference path="../Scripts/typings/angularjs/angular.d.ts" var contactsApp; contactsApp.controller('ContactsController', function ContactsController($scope, contactData) { $scope.sortOrder = 'last'; $scope.hideMessage = "Hide Details"; $scope.showMessage = "Show Details"; $scope.contacts = contactData.getContacts(); $scope.toggleShowDetails = function (contact) { contact.showDetails = !contact.showDetails; return contact.showDetails; }; }); //# sourceMappingURL=contactsController.js.map

Module und Klassendefinitionen hinzufügen

Mit Typanmerkungen in Ihrem Code geben Sie statischen Analyse-Tools die Möglichkeit, Fehler in Ihrem Code zu finden und zu melden. Die gilt für alle Bereiche von IntelliSense und lint-ähnlicher Analyse bis hin zu Fehlern und Warnungen zur Compilezeit.

Ein weiterer großer Vorteil von TypeScript gegenüber JavaScript ist eine bessere Syntax für die Bereichsdefinition von Typen. Mit dem module-Schlüsselwort können Sie in TypeScript Definitionen innerhalb eines Bereichs platzieren und Konflikte mit Typen aus anderen Modulen vermeiden, die denselben Namen verwenden.

Obwohl die contacts-Beispielanwendung nicht besonders umfangreich ist, sollten Sie die Typdefinitionen dennoch in Modulen platzieren, um Konflikte zu vermeiden. In diesem Beispiel platziere ich contactsController und die anderen von mir definierten Typen in ein Modul namens Rolodex:

module Rolodex { // Elided }

Ich verwende das export-Schlüsselwort in keiner der Definitionen in diesem Modul. Dies bedeutet, dass die Typen im Rolodex-Modul nur von innerhalb dieses Moduls referenziert werden können. Ich werde das export-Schlüsselwort zu den Schnittstellen in diesem Modul hinzufügen und diese Typen später verwenden, wenn ich den contactsData-Code migriere. Außerdem werde ich den Code für den ContactsController von einer Funktion zu einer Klasse ändern. Diese Klasse benötigt einen Konstruktor zur Initialisierung, enthält jedoch keine weiteren öffentlichen Methoden (siehe Abbildung 4).

Abbildung 4 Änderung von ContactsController von einer Funktion zu einer Klasse

export class ContactsController { constructor($scope: IContactsScope, contactData: any) { $scope.sortOrder = 'last'; $scope.hideMessage = "Hide Details"; $scope.showMessage = "Show Details"; $scope.contacts = contactData.getContacts(); $scope.toggleShowDetails = function (contact) { contact.showDetails = !contact.showDetails; return contact.showDetails; } } }

Mit diesem neuen Typen ändert sich der Aufruf an contactsApp.controller. Der zweite Parameter ist nun vom Typ class und nicht mehr wie bisher function. Der erste Parameter der controller-Funktion ist der Name des Controllers. Angular ordnet Controllernamen zu Konstruktorfunktionen zu. Bei jeder Referenzierung des ContactsController-Typs in der HTML-Seite ruft Angular den Konstruktor der ContactsController-Klasse auf:

contactsApp.controller('ContactsController', Rolodex.ContactsController);

Der Controller-Typ ist nun komplett von JavaScript zu TypeScript migriert. Die neue Version enthält Typanmerkungen für alle Variablen, die im Container definiert oder verwendet werden. In TypeScript könnte ich dies tun, ohne die restlichen Teile der Anwendung ändern zu müssen. Keine anderen Dateien wären betroffen. TypeScript lässt sich problemlos mit JavaScript mischen und daher problemlos zu existierenden JavaScript-Anwendungen hinzufügen. Das TypeScript-Typensystem verwendet Typrückschlüsse und strukturelle Typisierung, um die Interaktion zwischen TypeScript und JavaScript zu erleichtern.

Wenden wir uns nun der Datei contactData.js zu (siehe Abbildung 5). Diese Funktion verwendet die Angular-Factorymethode, um ein Objekt mit einer Liste von Kontakten zurückzugeben. Wie auch der Controller ordnet die Factorymethode Namen (contactData) zu einer Funktion zu, die den Dienst zurückgibt. Diese Konvention wird im Konstruktor des Controllers verwendet. Der zweite Parameter des Konstruktors hat den Namen contactData. Angular verwendet diesen Parameternamen, um die richtige Factory zu ermitteln. Wie Sie sehen arbeitet das Angular-Framework konventionsbasiert.

Abbildung 5 Die JavaScript-Version des contactData-Diensts

'use strict'; contactsApp.factory('contactData', function () { var contacts = [ { first: "Tom", last: "Riddle", address: "66 Shack St", city: "Little Hangleton", state: "Mississippi", zipCode: 54565, cellPhone: 6543654321, homePhone: 4532332133, workPhone: 6663420666 }, { first: "Antonin", last: "Dolohov", address: "28 Kaban Ln", city: "Gideon", state: "Arkensas", zipCode: 98767, cellPhone: 4443332222, homePhone: 5556667777, workPhone: 9897876765 }, { first: "Evan", last: "Rosier", address: "28 Dominion Ave", city: "Notting", state: "New Jersey", zipCode: 23432, cellPhone: 1232343456, homePhone: 4432215565, workPhone: 3454321234 } ]; return { getContacts: function () { return contacts; }, addContact: function(contact){ contacts.push(contact); return contacts; } }; })

Ändern Sie zunächst erneut die Erweiterung der Datei von .js zu .ts. Die Datei lässt sich problemlos kompilieren, und die JavaScript-Ausgabe ist der TypeScript-Quelldatei sehr ähnlich. Nun werde ich Code in die contactData.ts-Datei im Rolodex-Modul einfügen. Damit wird der gesamte Code der Anwendung in derselben logischen Partition platziert.

Anschließend werde ich die contactData-Factory zu einer Klasse ändern. Deklarieren Sie den Typ der Klasse als ContactDataServer. Anstelle einer Funktion, die ein Objekt mit den beiden Methoden als Eigenschaften zurückgibt, kann ich nun einfach die Methoden als Mitglieder eines ContactDataServer-Objekts definieren. Die Ausgangsdaten sind nun Datenelemente eines Objekts vom Typ ContactDataServer. Diesen Typ muss ich auch im Aufruf an contactsApp.factory verwenden:

contactsApp.factory('contactsData', () => new Rolodex.ContactDataServer());

Der zweite Parameter ist eine Funktion, die einen neuen ContactDataServer zurückgibt. Die Factory erstellt das Objekt bei Bedarf. Wenn ich versuche, diese Version zu kompilieren und auszuführen, erhalte ich Compilerfehler, da der Typ ContactDataServer im Rolodex-Modul nicht exportiert wird. Er wird jedoch im Aufruf an contacts­App.factory referenziert. Dies ist ein weiteres Beispiel für die Toleranz des TypeScript-Typensystems zur Erleichterung von Migrationsvorgängen. Ich kann diesen Fehler korrigieren, indem ich das export-Schlüsselwort zur ContactDataServer-Klassendeklaration hinzufüge.

In Abbildung 6 sehen Sie die endgültige Version. Beachten Sie, dass ich Typinformationen für das Array von Kontakten und den Eingangsparameter der addContact-Methode hinzugefügt habe. Die Typanmerkungen sind optional—der Code ist auch ohne sie gültiges TypeScript. Sie sollten jedoch nach Möglichkeit immer alle notwendigen Typinformationen zu Ihrem TypeScript-Code hinzufügen, da dies bei der Vermeidung von Fehlern im TypeScript-System hilft und Ihre Produktivität steigert.

Abbildung 6 Die TypeScript-Version von ContactDataServer

/// reference path="../Scripts/typings/angularjs/angular.d.ts" var contactsApp: ng.IModule; module Rolodex { export class ContactDataServer { contacts: IContact[] = [ { first: "Tom", last: "Riddle", address: "66 Shack St", city: "Little Hangleton", state: "Mississippi", zipCode: 54565, cellPhone: 6543654321, homePhone: 4532332133, workPhone: 6663420666, showDetails: true }, { first: "Antonin", last: "Dolohov", address: "28 Kaban Ln", city: "Gideon", state: "Arkensas", zipCode: 98767, cellPhone: 4443332222, homePhone: 5556667777, workPhone: 9897876765, showDetails: true }, { first: "Evan", last: "Rosier", address: "28 Dominion Ave", city: "Notting", state: "New Jersey", zipCode: 23432, cellPhone: 1232343456, homePhone: 4432215565, workPhone: 3454321234, showDetails: true } ]; getContacts() { return this.contacts; } addContact(contact: IContact) { this.contacts.push(contact); return this.contacts; } } } contactsApp.factory('contactsData', () => new Rolodex.ContactDataServer());

Nach der Erstellung der neuen ContactDataServer-Klasse werde ich nun eine letzte Änderung am Controller vornehmen. Sie erinnern sich, dass der zweite Parameter des contactsController-Konstruktors der Datenserver war. Nun kann ich die Typensicherheit dieses Code verbessern, indem ich deklariere, dass der folgende Parameter vom Typ ContactDataServer sein muss:

constructor($scope: IContactsScope, contactData: ContactDataServer) {

Problemlose Migrationen von JavaScript zu TypeScript

TypeScript bietet noch viel mehr Features als die hier vorgestellten. Bei der Arbeit mit TypeScript lernen Sie dessen Vorzüge zu schätzen. Je intensiver Sie die TypeScript-Erweiterungen für Ihr JavaScript verwenden, desto produktiver werden Sie arbeiten. Die TypeScript-Typanmerkungen wurden entwickelt, um eine problemlose Migration von JavaScript zu TypeScript zu ermöglichen. Behalten Sie stets im Gedächtnis, dass TypeScript eine strenge Obermenge von JavaScript ist. Dies bedeutet, dass jeder gültige JavaScript-Code auch gleichzeitig gültiges TypeScript ist.

Außerdem sind TypeScript-Typanmerkungen sehr schlicht gehalten. Sie werden nur an den angegebenen Stellen geprüft, und Sie werden nicht dazu gezwungen, die Anmerkungen überall zu verwenden. Dies ist sehr hilfreich bei der Migration von JavaScript zu TypeScript.

Außerdem unterstützt das TypeScript-Typensystem strukturelle Typisierung. Wenn Sie Schnittstellen für wichtige Typen definieren, nimmt das TypeScript-Typensystem automatisch an, dass jedes Objekt mit den entsprechenden Methoden und Eigenschaften diese Schnittstelle implementiert. Sie müssen die Schnittstellen-Implementierungen nicht bei jeder Klassendefinition angeben. Anonyme Objekte können mit der strukturellen Typisierung ebenfalls Schnittstellen implementieren.

Die Summe dieser Features ebnet Ihnen den Weg bei der Migration Ihrer Codebasis von JavaScript zu TypeScript. Je weiter Sie diesen Weg beschreiten, desto mehr Nutzen ziehen Sie aus der statischen Codeanalyse von TypeScript. Versuchen Sie dabei stets, möglichst viel Sicherheit aus TypeScript zu gewinnen. Während der Migration funktioniert Ihr existierender JavaScript-Code als gültiges TypeScript, das die TypeScript-Typanmerkungen noch nicht verwendet. Der Übergang erfolgt völlig reibungslos. Es gibt keinen Grund dafür, TypeScript nicht für Ihre aktuellen JavaScript-Anwendungen zu verwenden.

Bill Wagner ist der Autor des Bestsellers “Effective C#” (2004), aktuell in der zweiten Auflage, und “More Effective C#” (2008), beide bei Addison-Wesley Professional erschienen. Außerdem hat er die Videos "C# Async Fundamentals LiveLessons" und "C# Puzzlers" für Pearson Education informIT geschrieben. Sie finden seinen sehr aktiven Blog unter thebillwagner.com und erreichen ihn unter bill.w.wagner@outlook.com.

Unser Dank gilt dem folgenden technischen Experten von Microsoft für die Durchsicht dieses Artikels: Jonathan Turner
Jonathan Turner ist Program Manager für das TypeScript-Team bei Microsoft und Co-Designer der TypeScript-Sprache. Bevor er zu Microsoft kam, hat er an Clang/LLVM und der Chapel-Programmiersprache gearbeitet.