microsoft / microsoft/TypeScript

Feature request: machine-readable (JSONL) diagnostics output

オープン
#63,632 コメント 6 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Awaiting More Feedback Suggestion
主要言語
Go
スター
111k
フォーク
14.3k
平均マージ
2日 4時間
マージ済み PR(30日)
132

説明

Background

Type-checking integrations that run alongside a dev server - e.g., vite-plugin-checker, or a NestJS-style backend that auto-restarts once a change type-checks cleanly - need to know, after every file change, whether the project currently has type errors. There are a few ways to get that from tsc today, but they have downsides:

  1. Re-run tsc --noEmit on each change. Simple to consume (process exit code), but every run is a cold check - no incremental reuse - so it's slow on a real codebase and adds latency to every save, especially on a large codebase or many changes back to back.
  2. Run tsc --watch --noEmit once and parse its stdout. This is the fast path: the watcher reuses program state and only rechecks what changed. But the output is built for humans, not machines. This causes code like this. While this is faster, it's not ideal, as any changes to the response structure or copy will cause the script to break.

As a side QOL improvement, it will allow for easier logging of the errors in CI/CD - instead of trying to figure out multiline errors, it can now be easily streamed into monitoring systems.

Proposal

A single flag that switches the entire console output stream to JSONL. This is deliberately all-or-nothing: when enabled, nothing is written as free text, so a consumer can readline → JSON.parse every line without a parser mode-switch. This also composes with --watch and --noEmit, which reuse the same reporters.

Examples of proposed output:

{"type":"diagnostic","category":"error","code":2304,"file":"src/a.ts","start":{"line":3,"character":9},"end":{"line":3,"character":12},"message":"Cannot find name 'foo'.","relatedInformation":[]}
{"type":"summary","errors":1,"warnings":0}
{"type":"status","code":6032,"message":"File change detected. Starting incremental compilation..."}
{"type":"diagnostic","category":"error","code":2304,"file":"src/a.ts","start":{"line":3,"character":9},"end":{"line":3,"character":12},"message":"Cannot find name 'foo'.","relatedInformation":[]}
{"type":"summary","errors":0,"warnings":0}
Flag

Off the top of my head, there are a couple of ways to name the flag:

  1. --json - while this repeats the same approach as --pretty, it can be confused with other configurations like resolveJsonModule.
  2. --pretty json - convert --pretty from a simple boolean to an advanced combo of boolean and enum. The side problem is that currently, the tsconfig.json field pretty is a boolean, and at first glance, there are no union types in the JSON parser and validator.
  3. --diagnosticsFormat json - the most distinct option, but can confuse when the user tries to use --pretty and json.

To my personal taste, it looks like microsoft/typescript-go#2 is the best option. I'm not a maintainer of this codebase, so I will leave it to core contributors to decide.

stdout vs stderr

It might make sense to split into 2 streams for easier logging.

Implementation

With my limited knowledge of the codebase, I can see that it is possible to implement it by creating a new flag + adding an additional formatter in diagnostics.go.

I can work on a PR for this, but I need to know the decision about the flag before I try to implement it.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

まず diagnostics.go と、--pretty および --noEmit の既存の処理を読んでください。追加の formatter を実装する前に、flag の命名と stdout/stderr の動作について maintainer と調整してください。選択したモードが、diagnostics、summaries、watch のステータスメッセージを含め、一貫して machine-readable な JSONL を出力すれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
go, typescript
領域
cli, tooling
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
静か
明瞭さ
おおむね明確
初心者へのやさしさ
45/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。