TypeScriptが型を計算する方法を確認するにはどうすればよいですか?


18

問題:以前に定義された条件付きタイプからそれらのタイプを派生させる多くの条件付きタイプを含むファイルで作業していますが、これは非常に複雑になり、タイプがどのように派生しているかをデバッグすることが困難になりました。

TypeScriptコンパイラーがどのようにして条件付き型を決定し、パスを選択して最終的な型を導出するかを「デバッグ」または一覧表示する方法を見つけようとしています。

コンパイラオプションを調べましたが、その領域にはまだ何も見つかりません...

私が今探しているものに例えるとDEBUG=express:*、高速サーバーの動作を確認したい場合に使用できる種類の設定に相当します。

ただし、私が解決しようとしている実際の問題は、大規模で複雑な階層型定義で型が派生する方法を分解およびデバッグできることです。

重要な注意:TypeScriptプロジェクトのランタイム実行をデバッグするつもりはありません。TypeScriptコンパイラによって型が計算される方法をデバッグしようとしています。


優れたIDEを使用し、タイプをインスタンス化して、エディターで開いたソースファイルの値の上にカーソルを置きます。その提案を使用することで見逃してしまう追加の望ましい情報はありますか?
Patrick Roberts、

@PatrickRoberts-返信ありがとうございます。それを行うと、ネストされた条件型を持つ複合型を指します。次に、別の同様の複合型をポイントし、それが継続し、時には明白ではない方法で分岐します。型構築ブランチが発生している理由をデバッグする方法を考え出そうとしています。
ガイ

1
あなたの質問は、これを実証するための具体的な例から利益を得ると思います。以前にあなたが説明している状況にも遭遇しましたが、通常、回避策には、型がより不透明になるように書き直すことが含まれていることを見つけます(たとえば、その展開を試みるinterfaceジェネリックtypeではなく、自己文書化されたコンテナー名を持つジェネリックIDEのツールチップでの定義)またはソースをリファクタリングするだけで、複雑な条件付きタイプの使いすぎを完全に回避できます。
Patrick Roberts、

このレポをHapi / Joi @ 16にアップグレードして型生成をデバッグしようとする@PatrickRobertsが、この質問の原因です。github.com/TCMiranda/joi-extract-type
ガイ

@PatrickRobertsこれは、コンテキストのアップグレード自体について説明する特定の問題です。github.com/TCMiranda/joi-extract-type/issues/22
Guy

回答:


1

typescriptには、目的の情報をログアウトするための組み込みのメカニズムはありません。ただし、内部の作業を理解することに興味がある場合は、条件付き型の実際の解決が行われるソースコード内の場所を以下に示します。

でこれらの場所を見てくださいchecker.ts

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


添付されているのは、私が不用意に組み立てた半完成のtypescriptプラグインです。の生データ構造をログアウトしConditionalTypeます。この構造体を理解するには、types.ts ln:4634を確認してください。

このプラグインのUXはひどいですが、その構造体は、typescriptが条件型の最終的な値をどのように決定するかを示しています。

このプラグインを実行するための厄介な詳細な手順:

  1. mkdir my-ts-plugin && cd my-ts-plugin
  2. touch package.json そして書く { "name": "my-ts-plugin", "main": "index.js" }
  3. yarn add typescript fast-safe-stringify
  4. このスニペットをにコピーして貼り付けindex.ts、tscを使用してコンパイルしてindex.js
  5. yarn link
  6. cdあなた自身のtsプロジェクトのディレクトリに、実行しますyarn link my-ts-plugin
  7. { "compilerOptions": { "plugins": [{ "name": "my-ts-plugin" }] } }あなたに追加tsconfig.json
  8. (.vscode/settings.json)この行を設定するワークスペースに追加:{ "typescript.tsdk": "<PATH_TO_YOUR_TS_PROJECT>/node_modules/typescript/lib" }
  9. vscodeコマンドパレットを開いて実行します。
    1. TypeScript: Select TypeScript Version... -> Use Workspace Version
    2. TypeScript: Restart TS Server
    3. TypeScript: Open TS Server Log
  10. プラグインのログアウトを確認できるはず"PLUGIN UP AND RUNNING"です。tsコードファイルを開き、条件付きタイプのノードにカーソルを合わせると、ログファイルに追加されたjooデータ構造体が表示されます。

@hackapeをありがとう。私はそれをハックしていて、VSCodeを使用しているときにインタラクティブに見ているものを興味深いリストのかなりのログに生成することができるので、どこにいるのかを知ることができません。そのプラグインを機能させる方法に関する良い説明。
ガイ

あなたに賞金を差し上げました。解決策は得られていませんが、プラグインを変更する部分にもっと努力を払えば、おそらくそこに到達でき、近い将来これに対するより良い解決策があるとは想像できません。あなたの助けと努力をありがとう!
ガイ

1
@Guyバウンティをありがとう。それで、私は昨日より多くの有用な結果を得るために、さらに数時間を費やしました。あなたが正しい。上記のデータ構造体は、条件付きタイプチェーンのASTっぽいオブジェクトをキャプチャしますが、これは解析された結果であり、評価された結果ではありません。評価の際に型リゾルバーが取る「理由」または条件付き分岐については、中間ステップすべての結果をダンプする必要があります。たとえば、debuggerを一時停止して、コールスタックのローカルスコープを手動で調べるようなものです。
ハッカペ

1
カスタムビルドタイプスクリプトを作成するようにgetConditionalType()in を変更しchecker.ts、途中で中間情報をダンプするための副作用ロジックを挿入しました。今回はもう少し便利なものを手に入れました。コードをクリーンアップして、後で要旨を添付します。
ハッカペ

1
@Guy the gist is here
hackape '11
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.