Repository: TypeScript
Issue: Document when `emitSkipped` is `true` in Compiler API
Labels: Needs Investigation

# Suggestion

## 🔍 Search Terms

`emitSkipped`, emit skipped

Only related issue I could find in this repo was #2290, which is ~7 years old, and I'm not sure is accurate anymore?

## ✅ Viability Checklist

My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).

It's a docs change, so no behavior change.

## ⭐ Suggestion

<!-- A summary of what you'd like to see added or changed -->

I help maintain [`rollup-plugin-typescript2`](https://github.com/ezolenko/rollup-plugin-typescript2), and, as such, rely heavily on the TS Compiler API and its docs.

Currently, the documentation for `emitSkipped` is virtually non-existent. It is only referenced in code samples in [this](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) Wiki page. How it works and why it may be `true` or `false` is never explained in the docs.

Doing a Google search for `emitSkipped` also gets very few results, that mostly point to the Wiki code samples, duplicates/forks of it, or a specific issue in `ts-node` or `ts-jest`. So effectively, there is no explanation to be found anywhere.
Diving into the [source code](https://github.com/microsoft/TypeScript/search?p=5&q=emitskipped) has not been particularly helpful either, as it also doesn't document `emitSkipped`. Similar for the test code.

This is _very_ confusing to many libraries that rely on TS Compiler API and their users, so having explicit documentation for this would be _very_ helpful.
(As would improving the Compiler API docs in general).

As far as my current interpretation goes, `emitSkipped` is only `true` when there is:
1. a file outside of the `rootDir`
1. a file that would overwrite another file
1. `noEmitOnError: true` and there is a syntactic or semantic error
1. probably `noEmit: true` as well given the above?

Not sure if I'm missing other cases though, as I don't really have a source of truth to base this on.  

## 📃 Motivating Example

<!--
  If you were announcing this feature in a blog post, what's a short explanation that shows
  a developer why this feature improves the language?
-->

1. In my root cause analysis in https://github.com/ezolenko/rollup-plugin-typescript2/issues/264#issuecomment-1168213567 (search "`emitSkipped`", it's pretty long), I had to dig pretty deep to figure out what was going on, and it turns out it was a `rootDir` issue.
    - But the only way I could decipher that something was wrong was because `emitSkipped` was `true`, but there were no syntactic or semantic errors. So I didn't know _why_ it was `true`. I did a ton of searching and eventually I stumbled upon the answer in this issue comment in `ts-node`: https://github.com/TypeStrong/ts-node/issues/693#issuecomment-1166662842. 
That helped me figure out that the file was not in the `rootDir`, which was indeed the problem.
    - But TS itself gave no such error message, just `emitSkipped: true`. And there was no information on the Wiki or in the issues in TS's own repo; having to figure this out by looking through `ts-node`'s issues (which is not an official TS library) was pretty disconcerting to me.

1. In creating integration tests in https://github.com/ezolenko/rollup-plugin-typescript2/pull/371#issuecomment-1174339120, I legitimately couldn't figure out how to trigger `emitSkipped: true`.
    - It seems that semantic or syntactic errors no longer result in `emitSkipped: true`? #2290 seems to suggest this, but it also doesn't explain what scenarios `emitSkipped` would be `true` in (it's also a ~7 year old issue).
    - If that is accurate that type-check errors no longer result in `emitSkipped: true`, then that means we have a redundant check on [this line](https://github.com/ezolenko/rollup-plugin-typescript2/blob/8334c9b50fec01d9094b90b71a0913d4b87f94e1/src/index.ts#L204), and that my belief that `emitSkipped: true` means there was a diagnostic error is actually incorrect: https://github.com/ezolenko/rollup-plugin-typescript2/pull/344#discussion_r901820850
    
1. In my root cause analysis in https://github.com/ezolenko/rollup-plugin-typescript2/issues/254#issuecomment-1140503934, I discovered that `noEmitOnError: true` will cause files to return `emitSkipped: true`, even if those files are not the ones with the error (i.e. a different file has a syntax or semantic error).
    - Basically what https://github.com/microsoft/TypeScript/issues/2290#issuecomment-78203910 says, but this is not actually documented anywhere.
    - Also did not expect that, when `noEmitOnError: true`, all files would have `emitSkipped: true`, even ones without errors in them. This caused rpt2 to abort early, without printing out the type-checking failure, as the file with the type-check issue hadn't been reached yet. In https://github.com/ezolenko/rollup-plugin-typescript2/pull/338, I solved this by forcing `noEmitOnError: false` for now.
    
1. (Heavily related, I created a [label](https://github.com/ezolenko/rollup-plugin-typescript2/issues?q=label%3A%22topic%3A+TS+Compiler+API+Docs%22) in rpt2 for issues who's root cause is effectively due to lack of Compiler API docs, so we just didn't know to handle such a situation)
    - (This encompasses `emitSkipped` and `noEmitOnError` as mentioned above, as well as needing to implement `realpath` for `LanguageServiceHost` to support monorepos with symlinks, i.e. `pnpm`, Lerna, etc, which is _completely_ undocumented)

## 💻 Use Cases

<!--
  What do you want to use this for?
  What shortcomings exist with current approaches?
  What workarounds are you using in the meantime?
-->

This is for most Compiler API users and would impact `rollup-plugin-typescript2` as well as related integrations such as `ts-jest`, `ts-node`, `ts-loader`, etc, etc.

The shortcomings with the current approach is that community integrations rely on a patchwork of a tiny amount of docs, issue comments in other TS integrations, and basically reverse-engineering the Compiler API to figure out how it works. Or, as another workaround, reading TypeScript's own source code or tests, with mixed results.