Wie kann ich sehen, wie TypeScript Typen berechnet?

18

Problem: Ich arbeite an einer Datei mit vielen bedingten Typen, die ihre Typen von zuvor definierten bedingten Typen ableiten. Dies ist sehr komplex und schwierig zu debuggen, wie ein Typ abgeleitet wird.

Ich versuche einen Weg zu finden, um zu "debuggen" oder aufzulisten, wie der TypeScript-Compiler seine Bestimmung für einen bedingten Typ vornimmt und einen Pfad auswählt, um den endgültigen Typ abzuleiten.

Ich habe die Compiler-Optionen durchgesehen und noch nichts in diesem Bereich gefunden ...

Eine Analogie zu dem, wonach ich gerade suche, entspricht der DEBUG=express:*Art der Einstellung, die man verwenden könnte, wenn man sehen möchte, was ein Express-Server tut.

Das eigentliche Problem, das ich zu lösen versuche, besteht jedoch darin, dekonstruieren und debuggen zu können, wie ein Typ in einer großen komplexen hierarchischen Typdefinition abgeleitet wird.

Wichtiger Hinweis: Ich versuche nicht, die Laufzeitausführung des TypeScript-Projekts zu debuggen. Ich versuche zu debuggen, wie die Typen vom TypeScript-Compiler berechnet werden.

Kerl
quelle
Verwenden Sie einfach eine gute IDE, instanziieren Sie Ihren Typ und bewegen Sie den Mauszeiger über den Wert in der in Ihrem Editor geöffneten Quelldatei. Gibt es einige zusätzliche gewünschte Informationen, die Sie bei Verwendung dieses Vorschlags vermissen?
Patrick Roberts
@PatrickRoberts - danke für die Antwort. Wenn ich das mache, zeigt es auf einen komplexen Typ, der verschachtelte bedingte Typen hat. Das wiederum weist auf einen anderen ähnlich komplexen Typ hin und es geht weiter und manchmal verzweigt es sich auf eine Weise, die nicht offensichtlich ist. Ich versuche herauszufinden, wie ich debuggen kann, warum diese Art von Konstruktionszweig stattfindet.
Guy
1
Ich denke, Ihre Frage würde von einem konkreten Beispiel profitieren, um dies zu demonstrieren. Ich bin auch auf die Situation gestoßen, die Sie zuvor beschrieben haben, aber normalerweise finde ich, dass die Problemumgehung darin besteht, die Typen so umzuschreiben, dass sie entweder undurchsichtiger sind (z. B. ein Generikum interfacemit einem selbstdokumentierenden Containernamen anstelle eines Generikums type, das versucht, es zu erweitern Definition im Tooltip der IDE) oder einfach das Refactoring der Quelle, um eine übermäßige Verwendung komplexer bedingter Typen vollständig zu vermeiden.
Patrick Roberts
@PatrickRoberts, der versucht, dieses Repo auf Hapi / Joi @ 16 zu aktualisieren und die Typgenerierung zu debuggen, führte zu dieser Frage. github.com/TCMiranda/joi-extract-type
Guy
@PatrickRoberts Dies ist das spezielle Problem, bei dem das Upgrade selbst für den Kontext erörtert wird. github.com/TCMiranda/joi-extract-type/issues/22
Guy

Antworten:

1

In Typoskript ist kein Mechanismus integriert, mit dem die gewünschten Informationen abgemeldet werden können. Wenn Sie jedoch daran interessiert sind, die interne Arbeit zu verstehen, finden Sie hier die Stelle im Quellcode, an der die tatsächliche Auflösung von bedingten Typen erfolgt.

Schauen Sie sich diese Orte in an checker.ts.

ln: 13258 instantiateTypeWorker()
ln: 12303 getConditionalType()
ln: 12385 getTypeFromConditionalTypeNode()
ln: 12772getTypeFromTypeNode()


Im Anhang befindet sich ein halbfertiges Typoskript-Plugin, das ich nachlässig zusammengestellt habe. Es protokolliert die Rohdatenstruktur von a ConditionalType. Um diese Struktur zu verstehen, überprüfen Sie types.ts ln: 4634.

UX dieses Plugins ist schrecklich, aber diese Struktur sagt Ihnen, wie Typoskript den Endwert eines bedingten Typs entscheidet.

Einige ärgerlich detaillierte Anweisungen, um dieses Plugin zum Laufen zu bringen:

  1. mkdir my-ts-plugin && cd my-ts-plugin
  2. touch package.json und schreibe { "name": "my-ts-plugin", "main": "index.js" }
  3. yarn add typescript fast-safe-stringify
  4. Kopieren Sie dieses Snippet index.tsund fügen Sie es mit tsc einindex.js
  5. yarn link
  6. cdFühren Sie nun das Verzeichnis Ihres eigenen ts-Projekts ausyarn link my-ts-plugin
  7. fügen Sie { "compilerOptions": { "plugins": [{ "name": "my-ts-plugin" }] } }Ihrem hinzutsconfig.json
  8. Zum Arbeitsbereich hinzufügen, indem (.vscode/settings.json)diese Zeile festgelegt wird:{ "typescript.tsdk": "<PATH_TO_YOUR_TS_PROJECT>/node_modules/typescript/lib" }
  9. Öffnen Sie die vscode-Befehlspalette und führen Sie Folgendes aus:
    1. TypeScript: Select TypeScript Version... -> Use Workspace Version
    2. TypeScript: Restart TS Server
    3. TypeScript: Open TS Server Log
  10. Sie sollten in der Lage sein, die Abmeldung des Plugins zu sehen. "PLUGIN UP AND RUNNING"Öffnen Sie nun eine ts-Codedatei und bewegen Sie den Mauszeiger über einen Knoten vom bedingten Typ. Sie sollten eine lange json-Datenstruktur sehen, die der Protokolldatei hinzugefügt wurde.
Hackape
quelle
Danke für das @hackape. Ich habe mich damit herumgetrieben und kann einige Protokolle erstellen, die interessant sind und ziemlich genau auflisten, was ich bei der Verwendung von VSCode interaktiv sehe, sodass ich nicht viel weiter komme als bisher. Gute Anweisungen, wie man das Plugin zum Laufen bringt.
Guy
Ich habe dir das Kopfgeld gegeben. Obwohl es mich nicht zu der Lösung gebracht hat, denke ich, dass ich mit mehr Aufwand meinerseits das Plugin modifizieren könnte, um dorthin zu gelangen, und ich kann mir nicht vorstellen, dass es in naher Zukunft eine bessere Lösung dafür gibt. Vielen Dank für Ihre Hilfe und Mühe!
Guy
1
@ Guy Danke für das Kopfgeld. Also habe ich gestern noch ein paar Stunden damit verbracht, ein nützlicheres Ergebnis zu erzielen. Du hast recht. Die obige Datenstruktur erfasst das AST-ish-Objekt der bedingten Typenkette, aber es ist nur das analysierte Ergebnis, nicht das ausgewertete Ergebnis. Was das "Warum" oder den bedingten Zweig betrifft, den der Typauflöser bei der Auswertung verwendet, müssen die Ergebnisse aller Zwischenschritte ausgegeben werden, z. B. debuggerirgendwo eine Pause einlegen und dann die lokalen Bereiche in den Aufrufstapeln manuell durchsuchen.
Hackape
1
Ich veränderte die getConditionalType()in checker.tseinen benutzerdefinierten Build Typoskript zu machen, einige Nebeneffekt Logik Einfügen auf dem Weg Zwischen Info auskippen. Und diesmal habe ich etwas Nützlicheres. Ich werde meinen Code bereinigen und später einen Kern anhängen.
Hackape
1
@ Guy das Wesentliche ist hier
Hackape