Statische Analyse

Bei der statischen Analyse wird Ihr Code automatisch geprüft, ohne dass er tatsächlich ausgeführt wird oder einen automatisierten Test schreiben muss. Diese Art von Tests haben Sie wahrscheinlich schon gesehen, wenn Sie eine IDE wie VSCode verwenden. Die von TypeScript durchgeführte Typprüfung ist eine Art statische Analyse und kann unter Fehlern oder Warnungen als verzerrte Linien angezeigt werden.

ESLint

ESLint ist ein Tool, das Feedback zu möglichen Problemen in Ihrer Codebasis geben kann. Diese Probleme sind möglicherweise typsicher,haben aber schon Fehler oder ein nicht standardmäßiges Verhalten. Mit ESLint können Sie eine Reihe von Regeln anwenden, die auf Ihrer Codebasis geprüft werden, einschließlich vieler Regeln aus dem Set „Empfohlen“.

Ein gutes Beispiel für eine ESLint-Regel ist ihre no-unsafe-finally-Regel. Dadurch wird verhindert, dass Sie Anweisungen schreiben, die den Steuerungsablauf Ihres Programms in einem finally-Block ändern. Das ist eine sehr gute Regel, weil das eine ungewöhnliche Art und Weise ist, um JavaScript-Code zu schreiben, der möglicherweise schwer zu verstehen ist. Es ist jedoch auch etwas, das bei einer fehlerfreien Codeüberprüfung erkannt werden sollte.

  try {
    const result = await complexFetchFromNetwork();
    if (!result.ok) {
      throw new Error("failed to fetch");
    }
  } finally {
    // warning - this will 'overrule' the previous exception!
    return false;
  }

Daher ist ESLint kein Ersatz für einen fehlerfreien Überprüfungsprozess (und einen Styleguide, der definiert, wie Ihre Codebasis aussehen soll), da es nicht jeden unorthodoxen Ansatz erfassen kann, den ein Entwickler in Ihre Codebasis einführen könnte. Der Leitfaden zu den englischen Vorgehensweisen in der Google-Hilfe enthält einen kurzen Abschnitt zur einfachen Bedienung.

Mit ESLint können Sie eine Regel außer Kraft setzen und Code als „zulässig“ annotieren. Sie können beispielsweise die vorherige Logik zulassen, indem Sie sie wie folgt annotieren:

  finally {
    // eslint-disable-next-line no-unsafe-finally
    return false;
  }

Wenn Sie ständig gegen eine Regel verstoßen, sollten Sie sie deaktivieren. Diese Tools ermutigen Sie, Code auf eine bestimmte Weise zu schreiben. Ihr Team ist jedoch möglicherweise daran gewöhnt, Code anders zu schreiben, und sich der Risiken dieses Ansatzes bereits bewusst.

Schließlich kann das Aktivieren statischer Analysetools auf einer großen Codebasis zu viel nicht hilfreichem Rauschen (und viel Arbeit bei der Refaktorierung) von Code führen, der ansonsten gut funktionierte. Es ist also einfacher, die Funktion zu einem frühen Zeitpunkt im Lebenszyklus eines Projekts zu aktivieren.

ESLint-Plug-ins für die Browserunterstützung

Sie können ESLint ein Plug-in hinzufügen, das die Verwendung von APIs meldet, die nicht allgemein oder von Ihrer Zielbrowserliste nicht unterstützt werden. Das Paket eslint-plugin-compat kann Sie warnen, wenn eine API für Ihre Nutzer möglicherweise nicht verfügbar ist, sodass Sie nicht ständig selbst den Überblick behalten müssen.

Typprüfung für statische Analyse

Beim Erlernen von JavaScript stellen neue Entwickler in der Regel fest, dass es sich um eine schwach typisierte Sprache handelt. Es ist also möglich, eine Variable als einen Typ zu deklarieren und dann denselben Speicherort für etwas ganz anderes zu verwenden. Dies ähnelt Python und anderen Skriptsprachen, unterscheidet sich jedoch von kompilierten Sprachen wie C/C++ und Rust.

Diese Art von Sprache eignet sich gut für den Einstieg – und vermutlich ist es aufgrund dieser Einfachheit, die JavaScript so beliebt gemacht hat. Bei einigen Codebasen ist sie aber oft eine Schwachstelle oder zumindest etwas, durch das verwirrende Fehler auftreten können. Wenn Sie beispielsweise eine number übergeben, bei der ein string oder ein Objekttyp erwartet wurde, kann dieser falsch typisierte Wert über verschiedene Bibliotheken weitergegeben werden, bevor schließlich ein verwirrender TypeError entsteht.

TypeScript

TypeScript ist die gängigste Lösung für das Fehlen von Eingabeinformationen in JavaScript. In diesem Kurs wird es ausgiebig genutzt. Dies ist zwar kein Kurs zu TypeScript, aber es kann ein wichtiger Teil Ihrer Toolbox sein, da er statische Analysen bietet.

Ein kurzes Beispiel für diesen Code: Er erwartet einen Callback, bei dem ein string-Name und ein number-Alter angenommen werden:

const callback = (name: string, age: string): void => {
  console.info(name, 'is now', age, 'years old!');
};
onBirthday(callback);

Erzeugt den folgenden Fehler, wenn die Ausführung über TypeScript oder sogar dann erfolgt, wenn in einer IDE die Maus darüber bewegt wird:

bad.ts:4:12 - error TS2345: Argument of type '(name: string, age: string) => void' is not assignable to parameter of type '(name: string, age: number) => void'.
  Types of parameters 'age' and 'age' are incompatible.
    Type 'number' is not assignable to type 'string'.

4 onBirthday(callback);
             ~~~~~~~~

Found 1 error in bad.ts:4
Der Code aus dem vorherigen Beispiel, der in einer IDE mit der Fehlermeldung in einem Pop-up angezeigt wird.
VSCode, der angibt, dass ein falscher Typ übergeben wurde.

Das Ziel von TypeScript besteht letztendlich darin, Fehler wie diesen zu verhindern. Alter sollte ein number und kein string sein, der in Ihr Projekt eindringt. Diese Art von Fehler ist mit anderen Testtypen unter Umständen schwer zu erkennen. Darüber hinaus kann das Schriftsystem Feedback geben, bevor ein Test geschrieben wird. Dies kann das Schreiben von Code vereinfachen, da Sie frühzeitig Feedback zu Typfehlern erhalten, während Sie die Software entwickeln, und nicht, wenn der Code letztendlich ausgeführt wird.

Der schwierigste Teil der Verwendung von TypeScript ist die korrekte Einrichtung. Jedes Projekt benötigt eine tsconfig.json-Datei, die zwar hauptsächlich vom tsc-Befehlszeilentool verwendet wird, aber auch von IDEs wie VSCode zusammen mit vielen anderen Build-Tools und -Tools, einschließlich Vitest, gelesen wird. Diese Datei enthält Hunderte von Optionen und Flags. Hier finden Sie nützliche Ressourcen für die Einrichtung:

Allgemeine Tipps zu TypeScript

Wenn Sie TypeScript über eine tsconfig.json-Datei einrichten und verwenden, beachten Sie Folgendes:

  • Achten Sie darauf, dass Ihre Quelldateien tatsächlich vorhanden und geprüft sind. Wenn eine Datei „keine Fehler“ enthält, wird sie wahrscheinlich nicht geprüft.
  • Wenn Sie Typen und Schnittstellen in .d.ts-Dateien explizit beschreiben, können Sie die Codebasis leichter testen, anstatt sie beim Schreiben von Funktionen implizit zu beschreiben. Es ist einfacher, Simulationen und gefälschte Versionen von Code zu schreiben, wenn die beteiligten Schnittstellen klar sind. .

TypeScript implizit alle

Eine der leistungsstärksten und lohnendsten Konfigurationsoptionen von TypeScript ist das Flag noImplicitAny. Die Aktivierung ist jedoch oft auch am schwierigsten, insbesondere wenn Sie bereits eine große Codebasis haben. Das Flag noImplicitAny ist standardmäßig aktiviert, wenn Sie sich im strict-Modus befinden. Andernfalls wird es nicht aktiviert.

Dieses Flag sorgt dafür, dass die Funktion einen Fehler zurückgibt:

export function fibonacci(n) {
  if (n <= 1) {
    return 0;
  } else if (n === 2) {
    return 1;
  }
  return fibonacci(n - 1) + fibonacci(n - 2);
}

Als Leser ist es zwar ziemlich klar, dass n eine Zahl sein muss, TypeScript kann dies jedoch nicht sicher bestätigen. Wenn Sie VSCode verwenden und den Mauszeiger auf die Funktion bewegen, wird dies so beschrieben:

function fibonacci(n: any): any

Aufrufer dieser Funktion können einen Wert vom Typ any (ein Typ, der alle anderen Typen zulässt) übergeben, nicht nur einen number-Wert. Wenn Sie das Flag noImplicitAny aktivieren, können Sie diese Art von Code während der Entwicklung schützen, ohne dass Sie umfangreiche Geschäftslogiktests für Ihren Code schreiben müssen, um die falschen Datentypen an bestimmten Stellen zu übergeben.

Die einfache Lösung besteht darin, sowohl das n-Argument als auch den Rückgabetyp von fibonacci als number zu markieren.

Das Flag noImplicitAny hindert Sie nicht daran, any explizit in Ihre Codebasis zu schreiben. Sie können trotzdem eine Funktion schreiben, die den Typ any annimmt oder zurückgibt. Sie sorgt lediglich dafür, dass Sie jeder Variablen einen Typ zuweisen.