TypeScript macht durch seine statische Typisierung den Code sicherer und lesbarer. Dies gilt nicht nur für den eigenen Code, sondern auch für den Umgang mit Drittanbieter-Bibliotheken. Viele dieser Bibliotheken wurden ursprünglich in JavaScript geschrieben und enthalten von Haus aus keine Typinformationen. Hier kommt TypeScript ins Spiel: Mit Hilfe von @types, benutzerdefinierten Typdefinitionen und anderen Strategien lassen sich auch solche Bibliotheken in einem typensicheren Kontext verwenden. In diesem Artikel betrachten wir die Verwendung von Typdefinitionen für Drittbibliotheken und wie man mit Bibliotheken ohne vorhandene Typinformationen umgehen kann.
Verwendung von @types für Drittanbieter-Bibliotheken
Um Drittanbieter-Bibliotheken in TypeScript-Projekten zu nutzen, müssen Typinformationen vorliegen, damit TypeScript weiß, welche Datenstrukturen und Funktionen in der Bibliothek verfügbar sind. Für viele beliebte Bibliotheken gibt es offizielle oder von der Community erstellte Typdefinitionen, die über das npm-Paket @types bereitgestellt werden.
Der einfachste Weg, um Typdefinitionen zu installieren, ist die Verwendung von DefinitelyTyped, einem Repository, das viele Typdefinitionen für JavaScript-Bibliotheken enthält. Diese Definitionen können über npm installiert werden.
Zum Beispiel: Wenn du die Bibliothek `lodash` in deinem Projekt verwenden möchtest, kannst du die entsprechenden Typen so installieren:
npm install lodash @types/lodash --save
In diesem Fall wird `@types/lodash` installiert, was TypeScript die Typinformationen zur Verfügung stellt. Danach kannst du die Bibliothek wie gewohnt verwenden:
import _ from 'lodash';
const nums = [1, 2, 3];
const doubled = _.map(nums, (n) => n * 2);
console.log(doubled); // Ausgabe: [2, 4, 6]
Dank der Typinformationen von `@types/lodash` kann TypeScript erkennen, welche Methoden in Lodash verfügbar sind und welchen Typ sie zurückgeben.
Eigenen Typdefinitionen erstellen
Manchmal gibt es keine vorgefertigten Typdefinitionen für eine Bibliothek oder du möchtest eine interne Bibliothek typisieren. In solchen Fällen kannst du eigene Typdefinitionen erstellen. Dies geschieht durch das Erstellen einer sogenannten Declaration File mit der Endung `.d.ts`.
Nehmen wir an, du hast eine JavaScript-Bibliothek `myLibrary.js`, und du möchtest dafür Typen bereitstellen. Du erstellst eine Typdefinitionsdatei `myLibrary.d.ts`:
// myLibrary.d.ts
declare module "myLibrary" {
export function greet(name: string): string;
export function add(x: number, y: number): number;
}
Diese Datei beschreibt die Oberfläche der Bibliothek `myLibrary` und sagt TypeScript, welche Funktionen verfügbar sind und welche Typen sie verwenden. Danach kannst du die Bibliothek in deinem TypeScript-Projekt typisiert verwenden:
import { greet, add } from "myLibrary";
console.log(greet("Philipp")); // Ausgabe: Hello, Philipp
console.log(add(2, 3)); // Ausgabe: 5
Das Erstellen eigener Typdefinitionen ist besonders nützlich für interne Bibliotheken oder für Bibliotheken, die von der Community noch nicht typisiert wurden.
Umgang mit Bibliotheken ohne Typdefinitionen
Nicht jede JavaScript-Bibliothek hat sofort verfügbare Typdefinitionen, und manchmal möchtest du eine Bibliothek nutzen, die noch nicht typisiert ist. In solchen Fällen kannst du TypeScript auf verschiedene Weisen dazu bringen, mit der Bibliothek zu arbeiten, ohne die Typensicherheit komplett zu verlieren.
Wenn es keine Typdefinitionen gibt und du die Bibliothek trotzdem verwenden musst, kannst du sie zunächst als `any` deklarieren. Dadurch verliert TypeScript für diese Variable jedoch die Typüberprüfung.
// Annahme: myUnTypedLibrary hat keine Typdefinitionen
const myLib: any = require("myUnTypedLibrary");
const result = myLib.doSomething(); // Keine Typprüfung, result ist vom Typ 'any'
Dies sollte jedoch nur eine vorübergehende Lösung sein, da die Verwendung von `any` die Vorteile der Typensicherheit aufhebt.
Du kannst TypeScript explizit mitteilen, dass ein Modul keine Typen hat, indem du eine allgemeine Typdeklaration hinzufügst. Dies geschieht in einer `.d.ts`-Datei:
// global.d.ts
declare module "myUnTypedLibrary";
Dies ermöglicht es dir, das Modul zu importieren, ohne dass TypeScript Fehler ausgibt, auch wenn keine detaillierten Typen vorhanden sind.
Du kannst TypeScript anweisen, eine bestimmte Zeile zu ignorieren, indem du einen `@ts-ignore` Kommentar hinzufügst. Dies sollte nur in Ausnahmefällen genutzt werden, da es Typprüfungen vollständig deaktiviert:
// @ts-ignore
const result = myUnTypedLibrary.doSomething();
Wenn du weißt, welche Typen von einer Bibliothek zurückgegeben werden, kannst du Type Assertions verwenden, um TypeScript diese Information mitzuteilen:
const result = myUnTypedLibrary.getData() as string;
console.log(result); // TypeScript weiß nun, dass result ein string ist
Type Assertions geben dir die Kontrolle über den Typ einer Variable, aber du solltest sie nur verwenden, wenn du sicher bist, dass die Typen korrekt sind.
Fazit
Der Umgang mit Drittanbieter-Bibliotheken in TypeScript ist dank @types und Typdefinitionen sehr flexibel. Für viele beliebte Bibliotheken stehen bereits Typdefinitionen zur Verfügung, die über npm installiert werden können. In Fällen, in denen keine Typdefinitionen existieren, hast du die Möglichkeit, eigene Typdefinitionen zu erstellen oder vorübergehend auf `any` oder Type Assertions zurückzugreifen. Indem du Typdefinitionen für Drittbibliotheken nutzt und erstellst, profitierst du von der vollständigen Typensicherheit in TypeScript, was langfristig zu besserem und stabilerem Code führt.