Repository: TypeScript
Issue: Source map `mappings` is sometimes empty
Labels: Bug,Help Wanted

# Bug Report

<!--
  Please fill in each section completely. Thank you!
-->

### 🔎 Search Terms

<!--
  What search terms did you use when trying to find an existing bug report?
  List them here so people in the future can find this one more easily.
-->
source map empty mappings

### 🕗 Version & Regression Information

<!-- When did you start seeing this bug occur?

"Bugs" that have existed in TS for a long time are very likely to be FAQs; refer to
  https://github.com/Microsoft/TypeScript/wiki/FAQ#common-bugs-that-arent-bugs

If possible, please try testing the nightly version of TS to see if it's already been fixed.
For npm: `typescript@next`
This is also the 'Nightly' version in the playground: http://www.typescriptlang.org/play/?ts=Nightly

Note: The TypeScript Playground can be used to try older versions of TypeScript.

Please keep and fill in the line that best applies:
-->
- This is the behavior as far back as TypeScript 3.3

### ⏯ Playground Link

<!--
  A link to a TypeScript Playground "Share" link which shows this behavior

  The TypeScript Workbench can be used for more complex setups, try
  https://www.typescriptlang.org/dev/bug-workbench/

  As a last resort, you can link to a repo, but these will be slower for us to investigate.
-->
[Playground link with relevant code](https://www.typescriptlang.org/play?module=1&inlineSourceMap=true&inlineSources=true&ts=3.3.3#code/KYDwDg9gTgLgBDAnmYcB2cC86CuBbAI2CgCgg)

### 💻 Code

<!-- Please post the relevant code sample here as well-->
```ts
export type n = number
```

### 🙁 Actual behavior

<!-- What happened, and why it was wrong -->
The generated source map looks like this:

```json
{
  "version": 3,
  "file": "input.js",
  "sourceRoot": "",
  "sources": [
    "input.tsx"
  ],
  "names": [],
  "mappings": "",
  "sourcesContent": [
    "export type n = number\n"
  ]
}
```

### 🙂 Expected behavior

<!-- What you expected to happen instead, and why -->
I expected something like this instead:

```json
{
  "version": 3,
  "file": "input.js",
  "sourceRoot": "",
  "sources": [
    "input.tsx"
  ],
  "names": [],
  "mappings": "AAAA",
  "sourcesContent": [
    "export type n = number\n"
  ]
}
```

The problem is that TypeScript generates an empty `mappings` value. This causes tools such as esbuild that process source maps to not carry through any mappings when the input is bundled with source maps enabled. The end user visible effect of this is a user using `tsc` to compile TypeScript to JavaScript, bundling the JavaScript with esbuild, and then being confused why there are intermediate build files in the final source map instead of the original TypeScript files. This was reported to me as a bug in esbuild (https://github.com/evanw/esbuild/issues/2767) but I think it should be considered a bug in TypeScript instead. My rationale:

* The content in the `sources` array is only ever referenced by the "zero-based index into the sources list" in a mapping. So if there are no mappings, then there is no reference to the sources array for esbuild to carry forward, and the name in the `sources` array will never be included.

* It would be incorrect for esbuild to assume that if there are no mappings but there is a single entry in the `sources` array, then esbuild should automatically generate a mapping from the start of the output code to the start of that single source. This is because esbuild doesn't have enough information to know whether the content of the source file is related to the code in the output or not. The code in the output could be entirely unrelated to the source file (one example scenario: https://github.com/evanw/esbuild/issues/2767#issuecomment-1364177552).

* Arguably the module shim output that TypeScript generates even when the file is empty (`"use strict"`, `__esModule`, etc.) should still be associated with the input source file in TypeScript's source map, since TypeScript is processing each file one-at-a-time so all code it generates relates to the input source file. It's ok for the `mappings` value to be empty if the output is empty (since there is nothing to map), but if the output is non-empty then I'd expect for `mappings` to also be non-empty.

I'm primarily reporting this for your awareness. You could also argue that the source map TypeScript generates _should_ have an empty `mappings` value because none of the statements in the file made it into the final output, and the fact that the source file is missing from the final bundled source map is actually correct. If so, then feel free to close this issue.