Von Johannes Schwegler
JavaScript ist eine Skriptsprache, die das Ausführen von Code in Webbrowsern ermöglicht und damit clientseitig eingesetzt wird. Mit der Entwicklung von Node.js und vielen weiteren Bibliotheken wurde JavaScript auch auf der Serverseite als neue Technologie eingeführt. Mit wachsendem JavaScript-Code wird die Codebasis jedoch tendenziell immer schwerer wartbar und wiederverwendbar. Dies ist unter anderem auf die schwache Typisierung der Programmiersprache zurückzuführen sowie auf den Mangel, in einem Kompilierungsschritt eine Fehlerüberprüfung durchführen zu können. Diese Punkte haben JavaScript lange Zeit daran gehindert, sich auch auf Unternehmensebene als vollwertige serverseitige Technologie durchzusetzen. Um diese Lücke zu schließen wurde Typescript entwickelt.
Was ist TypeScript?
TypeScript ist eine neue Art, JavaScript zu schreiben. Sie ist präziser, wenn es um die Deklaration von Variablen, Funktionen, Klassen und mehr geht.
Wer schon einmal eine Programmiersprache wie Java oder C# verwendet hat, weiß dass diese Sprachen bei der Deklaration von Variablen „strenger“ sind. Diese strenge Deklaration wird auch als statische Typisierung bezeichnet. JavaScript ist standardmäßig eine schwach typisierte Programmiersprache.
Während folgendes in JavaScript in Ordnung ist:
var post = 3 + [] // ergibt einen String mit Wert 3
…ist dies in Java / C# nicht möglich, da sich die Typen unterscheiden.
int post = 3 + [] // Error
Hier muss nämlich angegeben werden, ob die zu deklarierende Variable vom Typ Integer, Float, String, Boolean, Array oder beispielsweise List ist.
Ein Datentyp hilft dem Programm zu wissen, welche Art von Speicherplatz der zu deklarierenden Variable zuzuweisen ist. In JavaScript werden keine Typen deklariert, weil die JavaScript-Engine hinter den Kulissen den Typ und die Speicherzuweisung für uns verwaltet.
TypeScript ermöglicht es uns, Typen für unseren Code zu vergeben. Dieser Code wird anschließend in JavaScript kompiliert, damit er normal ausgeführt werden kann. So können Fehler in TypeScript bereits zur Kompilierung des Code entdeckt werden, siehe folgende Gegenüberstellung:
JavaScript | TypeScript | |
Wie werden Typen vergeben | Dynamisch | Statisch |
Werden Typen automatisch konvertiert | Ja | Nein |
Wann wird der Code auf Fehler geprüft? | Zur Ausführung | Zur Kompilierung |
Wann werden Fehler entdeckt? | Zur Ausführung | Zur Kompilierung |
Praktische Einführung
Wenn Sie TypeScript jetzt gleich ausprobieren möchten, gehen Sie am besten auf https://www.typescriptlang.org/, um die neueste Version von TypeScript auf Ihren Computer herunterzuladen.
Sie können auch den Node Package Manager (npm) verwenden, wenn Sie ein Fan von Node.js sind, um TypeScript mit dem folgenden Befehl herunterzuladen:
npm install -g typescript
Hiermit wird TypeScript global für Ihren Computer installiert.
Wenn alles funktioniert hat, sollten Sie dann in der Lage sein, TypeScript-Code in Ihrem bevorzugten Editor zu schreiben und ihn über die Befehlszeile mit dem Befehl tsc in reguläres JavaScript zu kompilieren.
Hierzu legen Sie einfach eine Datei mit der Endung .ts an. Nun können Sie beispielsweise folgenden Code im Editor eingeben:
let title:string = "TypeScript – Eine Einführung" let sentence:string = `Der Titel dieses Beitrag lautet ${title}`
Nachdem Sie nun die Datei gespeichert haben, kann TypeScript durch den folgenden CMD-Befehl zu JavaScript kompiliert werden.
tsc datei.ts
Nun sollte eine Datei mit der Endung .js generiert worden sein, die den übersetzten Code enthält.
Schauen wir uns an wie wir TypeScript einsetzen können und was es mit den oberen Deklarationen auf sich hat.
Variablen
In TypeScript können wir mit der folgenden Syntax definieren, welchen Typ unsere Variable haben soll.
let webforwards:string = "TypeScript - Eine Einführung" let year:int = 2020
Grundsätzlich deklarieren wir den Typ der Variable nach dem Variablennamen. Erst dann weisen wir durch den Zuweisungsoperator „=“ einen Wert zu.
Dies bringt zwar einen höheren Schreibaufwand mit sich, allerdings ist direkt ersichtlich, welchen Typ eine Variable hat.
Arrays und Tupel
Wir können unsere Variablen auch als Arrays oder Tupel definieren. In den beiden folgenden Fällen definieren wir einen Array (entweder mit der Syntax [] oder mit dem Schlüsselwort Array<>, wobei wir den Typ beides mal angeben).
let myArr:number[] = [1,2,3,4,5] let myArr:Array<String> = ['yolo', 'whazzup', 'rad', 'lol']
Ein Tupel verhält sich ähnlich wie ein Array, aber seine Werte müssen nicht zwingend einem einzigen Datentyp angehören.
let meineTupel:[string, number] = ["hello", 2]
Verwendet werden müssen dieselben Typen wie bei der Deklarationsreihenfolge, d.h. wir können meineTupel nicht als solches definieren:
meineTupel = [10,20]; //Type 'number' is not assignable to type 'string'
Im folgenden Beispiel ist die Substring-Methode nur für Werte verfügbar, die vom Typ String deklariert wurden, nicht vom Typ Number:
meineTupel[0].substr(0,1) meineTupel[1].substr(0,1) //Property 'substr' does not exist on type 'number'
Funktionen
Auch die Deklaration von Funktionen sieht in TypeScript etwas anders aus.
const getEvenNums = (num: number): number[] => { let arr = []; if (num < 2) return []; for (let i = 2; i <= num; i += 1) { if (i % 2 === 0) { arr.push(i); } } return arr; };
Wenn wir uns obrige Funktion anschauen, können wir sehen, dass die Funktion getEvenNums einen einzigen Parameter vom Typ number erwartet. Nach dem Doppelpunkt geben wir an, dass wir als Rückgabetyp einen Array vom Typ number vorsehen. Der Rest des Funktionskörpers befindet sich innerhalb der geschweiften Klammern. Sie können gerne versuchen, diesen Code zu kompilieren, um zu sehen, wie er in reinem JavaScript aussieht.
Void und Any
Häufig arbeiten Sie in JavaScript mit einer älteren Bibliothek, die nicht mit der Version ES6 oder TypeScript-Code kompatibel ist. Es ist möglich, dass Sie die Typen der Werte, die aus dieser älteren Bibliotheken abgerufen werden, nicht kennen. In diesen Fällen können Sie den Typ „any“ zum Speichern der Daten verwenden.
let val: any = $(".class").text() // speichert den Wert der text()-Funktion, es ist allerdings nicht klar, welchen Typ diese Funktion zurückgibt.
Void gibt dagegen an, dass eine Funktion keinen Rückgabewert hat. In regulärem JavaScript gibt der Interpreter hinter den Kulissen automatisch undefined zurück, wenn eine Funktion nicht explizit einen Wert zurückgibt. Deshalb sehen Sie, wenn Sie in Ihren Entwicklungswerkzeugen des Browsers die Funktion console.log verwendet haben, nach dem Protokollieren die Ausgabe „undefined“.
Wie in anderen Sprachen lässt sich das Schlüsselwort void auch verwenden um anzuzeigen, dass eine Funktion keinen Rückgabewert hat:
let beispiel = (nachricht: string): void => { console.log(nachricht); }
Interfaces
Ein Interface ist eine Möglichkeit, den Typ jeder Eigenschaft eines Objekts zu beschreiben. So könnten wir zum Beispiel in JavaScript schreiben:
let beitrag = { name: "TypeScript - Eine Einführung", author: "Johannes Schwegler", year: 2020 }
Während dieses Objekt syntaktisch in Ordnung ist, sind die Typen jeder Eigenschaft nicht definiert. Übergeben wir das Objekt nun an eine Funktion, so kann dies bei fehlenden Eigenschaften zu Fehlern führen. Durch den Einsatz von TypeScript können wir den Typ der jeweiligen Eigenschaft direkt angeben. Sollten wir nun eine Eigenschaft vergessen, wird bereits zur Kompilierung ein Fehler angezeigt.
interface Beitrag { name: string, author: string, year: number } let beitragsInfo = (beitrag: Beitrag):string => { return `Der Titel des Beitrag lautet ${beitrag.name}. Er wurde von ${beitrag.author} erstellt und im Jahr {beitrag.year} veröffentlicht.` } let beitrag = { name: "TypeScript - Eine Einführung", year: 2020 } console.log(beitragsInfo(beitrag)) /* Property 'author' is missing in type '{ name: string, author: string, year: number }' but required in type 'Beitrag'. */
Es gibt noch weitere Datentypen in TypeScript. Genauere Informationen finden Sie hier: https://www.typescriptlang.org/docs/handbook/basic-types.html
Webpack-Integration
Anstatt die Kompilierung von TypeScript jedesmal manuell durch den Befehl „tsc“ anstoßen zu müssen, kann man die TypeScript-Dateien auch durch Webpack überwachen lassen. Hierdurch wird automatisch durch jede Speicherung eine Kompilierung angestoßen.
Auf die Installation von Webpack wird an dieser Stelle nicht näher eingegangen. Die entsprechenden Infos dazu können jedoch hier nachgelesen werden: https://webpack.js.org/guides/getting-started/
Um nun TypeScript in unserem Projekt nutzen zu können müssen die folgenden Schritte durchgeführt werden.
1. Installation der Abhängigkeiten
npm install --save-dev typescript ts-loader
2. Erstellen einer ts.config – Datei
Die Datei dient zur Angabe von Komplilierungsoptionen für TypeScript. Beispielsweise kann die Zielversion unseres installierten JavaScripts durch die Eigenschaft „target:es5“ angeben werden. Somit wird der Code zu einer ältereren Version kompiliert, damit er auch in älteren Browsern oder Umgebungen verwendet werden kann.
{ "compilerOptions": { "noImplicitAny": true, "module": "es2015", "target": "es5", "allowJs": true, "allowSyntheticDefaultImports" : true, "esModuleInterop" : true } }
Toll ist auch, dass wir durch die Nutzung von TypeScript die Toolchain Babel nicht mehr benötigen, die bisher für die Konvertierung von ECMAScript 2015+-Code in eine rückwärtskompatible Version von JavaScript benötigt wurde.
3. Konfiguration der Webpack-Datei
Um nun TypeScript nutzen zu können müssen wir nur noch die „Entry“-Datei angeben sowie den sog. TS-Loader verwenden, der alle .ts und .tsx-Dateien lädt. Als Ausgabe erhalten wir dann den JavaScript-Code in der bundle.js-Datei.
const path = require('path'); module.exports = { entry: './src/index.ts', module: { rules: [ { test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/, }, ], }, resolve: { extensions: [ '.tsx', '.ts', '.js' ], }, output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, };
Das wars auch schon, nun sollten Sie in der Lage sein, TypeScript in ihren Projekten zu nutzen. Viel Spaß dabei!
Quellen:
https://www.typescriptlang.org/docs/handbook/basic-types.html
https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
Kommentare von hofmeister