Jak mogę zobaczyć, w jaki sposób TypeScript oblicza typy?

18

Problem: Pracuję nad plikiem, który ma wiele typów warunkowych, które wywodzą swoje typy z wcześniej zdefiniowanych typów warunkowych, a to stało się bardzo skomplikowane i trudne do debugowania w jaki sposób jest uzyskiwany typ.

Próbuję znaleźć sposób na „debugowanie” lub wyszczególnienie, w jaki sposób kompilator TypeScript ustala typ warunkowy i wybrał ścieżkę do uzyskania ostatecznego typu.

Przejrzałem opcje kompilatora i nie znalazłem jeszcze niczego w tym obszarze ...

Analogią do tego, czego teraz szukam, jest odpowiednik DEBUG=express:*rodzaju ustawienia, którego można użyć, jeśli chcesz zobaczyć, co robi serwer ekspresowy.

Jednak faktycznym problemem, który próbuję rozwiązać, jest możliwość zdekonstruowania i debugowania sposobu, w jaki typ jest uzyskiwany w dużej złożonej definicji typu hierarchicznego.

Ważna uwaga: Nie próbuję debugować wykonania środowiska wykonawczego projektu TypeScript. Próbuję debugować sposób obliczania typów przez kompilator TypeScript.

Chłopak
źródło
Wystarczy użyć dobrego IDE, utworzyć instancję typu i najechać wskaźnikiem myszy na wartość w pliku źródłowym otwartym w edytorze. Czy korzystając z tej sugestii brakuje Ci dodatkowych informacji?
Patrick Roberts,
@PatrickRoberts - dzięki za odpowiedź. Kiedy to robię, wskazuje na złożony typ, który zagnieżdżał typy warunkowe. To z kolei wskazuje na inny podobny złożony typ i wciąż się rozwija, a czasem rozgałęzia się w sposób, który nie jest oczywisty. Próbuję dowiedzieć się, jak debugować, dlaczego dzieje się ten typ branży budowlanej.
Guy
1
Myślę, że twoje pytanie skorzystałoby z konkretnego przykładu, który to udowodni. Zetknąłem się również z sytuacją, którą opisujesz wcześniej, ale zwykle uważam, że obejście tego problemu polega na przepisaniu typów tak, aby były albo bardziej nieprzejrzyste (np. Ogólny interfacez samokontrującą nazwą kontenera zamiast ogólnego, typektóry próbuje rozszerzyć jego definicja w podpowiedzi IDE) lub po prostu przeredaguj źródło, aby całkowicie uniknąć nadużywania złożonych typów warunkowych.
Patrick Roberts,
@PatrickRoberts próbuje uaktualnić to repozytorium do Hapi / Joi @ 16 i debugować generowanie typów, co prowadzi do tego pytania. github.com/TCMiranda/joi-extract-type
Guy
@PatrickRoberts jest to konkretny problem omawiający samą aktualizację w kontekście. github.com/TCMiranda/joi-extract-type/issues/22
Guy

Odpowiedzi:

1

W maszynopisie nie ma wbudowanego mechanizmu wylogowania żądanych informacji. Jeśli jednak jesteś zainteresowany zrozumieniem pracy wewnętrznej, oto miejsce w kodzie źródłowym, w którym faktycznie następuje rozwiązywanie typów warunkowych.

Spójrz na te miejsca w checker.ts.

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


W załączeniu jest niedokończona wtyczka maszynopisu, którą niedbale opracowałem. Wylogowuje surową strukturę danych ConditionalType. Aby zrozumieć tę strukturę, sprawdź types.ts ln: 4634.

UX tej wtyczki jest okropny, ale ta struktura mówi ci, jak maszynopis decyduje o końcowej wartości typu warunkowego.

Kilka irytująco szczegółowych instrukcji, aby uruchomić tę wtyczkę:

  1. mkdir my-ts-plugin && cd my-ts-plugin
  2. touch package.json i napisz { "name": "my-ts-plugin", "main": "index.js" }
  3. yarn add typescript fast-safe-stringify
  4. skopiuj i wklej ten fragment do index.ts, użyj tsc, aby go skompilowaćindex.js
  5. yarn link
  6. teraz cddo katalogu własnego projektu ts, uruchomyarn link my-ts-plugin
  7. dodaj { "compilerOptions": { "plugins": [{ "name": "my-ts-plugin" }] } }do swojegotsconfig.json
  8. dodaj do obszaru roboczego, ustawiając (.vscode/settings.json)ten wiersz:{ "typescript.tsdk": "<PATH_TO_YOUR_TS_PROJECT>/node_modules/typescript/lib" }
  9. otwórz paletę poleceń vscode i uruchom:
    1. TypeScript: Select TypeScript Version... -> Use Workspace Version
    2. TypeScript: Restart TS Server
    3. TypeScript: Open TS Server Log
  10. powinieneś być w stanie zobaczyć wylogowanie wtyczki "PLUGIN UP AND RUNNING", teraz otwórz plik kodu ts i najedź kursorem myszy na jakiś węzeł typu warunkowego, powinieneś zobaczyć dłuższą strukturę danych json dodaną do pliku dziennika.
hackape
źródło
Dzięki za to @hackape. Włamałem się do niego i mogę stworzyć logi, które są interesujące i zawierają listę tego, co widzę interaktywnie podczas korzystania z VSCode, więc nie dotarło to daleko poza mnie. Dobre instrukcje, jak uruchomić tę wtyczkę.
Guy
Dałem ci nagrodę. Mimo że nie doprowadziło mnie to do rozwiązania, myślę, że z większym wysiłkiem z mojej strony modyfikując tę ​​wtyczkę prawdopodobnie mógłbym się tam dostać i nie mogę sobie wyobrazić, że będzie lepsze rozwiązanie tego problemu w najbliższej przyszłości. Dzięki za pomoc i wysiłek!
Guy
1
@Guy Dzięki za nagrodę. Wczoraj spędziłem kilka godzin, starając się uzyskać bardziej użyteczny wynik. Masz rację. Struktura danych powyżej przechwytuje obiekt typu AST łańcucha typu warunkowego, ale jest to tylko przeanalizowany wynik, a nie wynik oceny. Jeśli chodzi o „dlaczego” lub jaką gałąź warunkową interpretuje typ podczas oceny, wymaga to odrzucenia wyników wszystkich pośrednich kroków, na przykład umieszczenia debuggergdzieś pauzy, a następnie ręcznego przeglądania lokalnych zasięgów w stosach wywołań.
hackape
1
Zmodyfikowałem getConditionalType()in, checker.tsaby utworzyć niestandardowy skrypt maszynowy, wstawiając logikę efektów ubocznych, aby po drodze zrzucić informacje pośrednie. I tym razem dostałem coś bardziej przydatnego. Wyczyszczę kod i dołączę później treść.
hackape
1
@Guy istota jest tutaj
hackape