ProgrammierungFrontend Entwickler

Wie funktioniert der Typisierungsmechanismus von importierten JavaScript-Modulen in TypeScript? Wie typisiert man einen Import, wenn die ursprüngliche JS-Datei keine Typen enthält? Welche Nuancen und Risiken gibt es bei der Verwendung von any im Import?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

Geschichte der Frage:

TypeScript ist dazu gedacht, statische Typisierung zu bestehenden JS-Anwendungen hinzuzufügen. Es stellt sich die Frage: Wie typisiert man einen Import, wenn wir ein externes oder eigenes Modul einbinden, das in reinem JavaScript geschrieben ist, wo es keine Typen gibt? In diesem Fall verwendet TypeScript sogenannte Deklarationsdateien (.d.ts), oder es leitet Typen automatisch ab (manchmal falsch).

Problem:

Wenn TypeScript beim Import keinen passenden Typbeschreibung findet, erhält die Variable den Typ any, was bedeutet, dass die Typensicherheit vollständig verloren geht. Dies kann zu Fehlern führen, die der Compiler nicht bemerkt, und zu Bugs zur Laufzeit. Oft vergessen Entwickler, die Typen für importierte Funktionen/Objekte explizit zu deklarieren.

Lösung:

  1. Für eigene JS-Module kann man die Typdeklarationen manuell schreiben (Dateien .d.ts).
  2. Für populäre Bibliotheken gibt es oft @types/-Pakete.
  3. Man kann die Typen beim Import explizit deklarieren und die Struktur des benötigten Objekts selbst beschreiben.
  4. Es wird empfohlen, any zu vermeiden, und wenn es nicht vermeidbar ist, den Geltungsbereich der Verwendung minimal einzuschränken.

Codebeispiel:

// 1. Explizite Typisierung des Imports eines JS-Moduls import myFunc from './myLib'; declare function myFunc(x: number): boolean; // 2. Import aus dem JS-Modul, für das die Datei myLib.d.ts mit export function myFunc(x: number): boolean; erstellt wurde. import { myFunc } from './myLib'; // 3. Importieren eines Moduls ohne Typisierung und explizites Beschreiben des Typs import * as legacy from './legacy'; const typedLegacy: { runTask: (name: string) => void } = legacy;

Wichtige Merkmale:

  • Bei fehlenden Deklarationen erhält der importierte Wert standardmäßig den Typ any, was die Typensicherheit verletzt.
  • Der beste Ansatz ist die Erstellung von .d.ts-Dateien für externe Module/eigene Bibliotheken.
  • Bei Bedarf ist es möglich, externe Funktionen/Module lokal über declare/Schnittstellen zu deklarieren.

Fangfragen.

Kann TypeScript die Typen eines importierten JS-Moduls automatisch ableiten, wenn keine Deklarationen vorhanden sind?

Nein, wenn die Datei in JavaScript geschrieben ist, ist TypeScript gezwungen, any anzunehmen und verliert somit die Typinformationen, außer in trivialen Fällen (export const x = 1;).

Kann man importierte Typen "erweitern", wenn neue Felder im JS-Modul erscheinen?

Nur wenn Sie die Deklarationsdatei (.d.ts) aktualisieren. Wenn die Typen in der .d.ts festgelegt sind, wird TypeScript sie als "Wahrheit" verwenden, neue Felder bleiben untypisiert oder führen zu einem Fehler.

Ist es sicher, ein externes JS-Modul in ein TypeScript-Projekt zu importieren, wenn es keine @types/ und Deklarationen gibt?

Nein, dies verringert die Sicherheit erheblich – die gesamte Arbeit mit dem Import ist untypisiert (any), der Compiler wird keine Fehler ausgeben, selbst wenn das Modul nicht verfügbar ist oder die API sich geändert hat. Die Arbeit mit solchen Modulen ist nur als vorübergehende Lösung zulässig, mit expliziter Typisierung oder Isolierung des Codes.

Typfehler und Anti-Pattern

  • Vergessen von Deklarationen (.d.ts) für externe Pakete
  • Blindes Vertrauen in implicit any beim Import von JS-Modulen
  • Verletzung der Grenzen von type-sicherem Code

Beispiel aus dem Leben

Negativer Fall

Ein Entwickler importiert eine externe JS-Bibliothek ohne Deklarationen und verwendet unsicher das API, wobei er den Typ any erhält. Nach dem Update der Bibliothek ändert sich die Signatur der Methoden, aber es treten keine Fehler auf, nur Bugs zur Laufzeit.

Vorteile:

  • Schnell und einfach, jedes JS-Modul zu integrieren

Nachteile:

  • Keine Garantien für Typensicherheit, Fehler bleiben bis zur Ausführung unentdeckt

Positiver Fall

Es wird eine Deklarationsdatei .d.ts erstellt oder ein @types/-Paket hinzugefügt, die API-Beschreibung entspricht genau dem ursprünglichen JS-Modul. Alle importierten Methoden sind typisiert, die IDE bietet Autocomplete-Unterstützung, alle Abweichungen zeigen einen Kompilierungsfehler an.

Vorteile:

  • Typensicherheit, Fehlerwarnung vor Ausführung
  • Unterstützung von Autocomplete und Dokumentation direkt im Code

Nachteile:

  • Es erfordert Zeit, um .d.ts zu schreiben, Unterstützung der Typen bei Updates des JS-Moduls