Repository: TypeScript
Issue: foo.ts is resolved before foo.d.ts even if the latter is in files[]
Labels: Suggestion,Help Wanted,Committed

Affects at least TS 2.7.2 and 2.6.2. This problem appears when compiling files separately, like we do under Bazel.

Imagine this simple app

`src/lib.ts`
```
export const a = 1;
```
`src/main.ts`
```
import {a} from './lib';
```

Imagine `lib.ts` was compiled separately, so there already exists
`dist/lib.d.ts`
```
export declare const a = 1;
```

Now, I want to compile `main.ts` as a separate program. Given  `src/tsconfig.json`

```
{
  "compilerOptions": {
    "rootDirs": [
      ".",
      "../dist"
    ],
    "outDir": "../dist",
    "declaration": true
  },

  "files": [
    "main.ts",
    // lib was compiled separately
    "../dist/lib.d.ts"
  ]
}
```

We see that `lib.d.ts` is already in the program before resolution begins. However the compiler resolves the import statement to the `lib.ts` file instead, adding it to the program, and tries to emit on top of an input, so the error is

```
$ ./node_modules/.bin/tsc -p src
error TS5055: Cannot write file '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/dist/lib.d.ts' because it would overwrite input file.
```

Okay, we didn't want `lib.ts` in the program, so we should just use `--noResolve` to prevent that, but it's also broken:
```
$ ./node_modules/.bin/tsc -p src --noResolve --traceResolution
======== Resolving module './lib' from '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/main.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
'rootDirs' option is set, using it to resolve relative module name './lib'.
Checking if '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/' is the longest matching prefix for '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib' - 'true'.
Checking if '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/dist/' is the longest matching prefix for '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib' - 'false'.
Longest matching prefix for '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib' is '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/'.
Loading 'lib' from the root dir '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/', candidate location '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib'.
Loading module as file / folder, candidate module location '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib', target file type 'TypeScript'.
File '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib.ts' exist - use it as a name resolution result.
======== Module name './lib' was successfully resolved to '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib.ts'. ========
src/main.ts(1,17): error TS2307: Cannot find module './lib'.
```

So far our workaround at Google is one of:
- use Bazel sandboxing to make the inputs appear in different places
- use our own custom compiler which elides any emit to files we don't expect

However under Bazel we sometimes cannot sandbox (eg. on Windows) and cannot use our custom compiler (eg. when we are compiling it)
so we are stuck.

I found that `ts.CompilerOptions.suppressOutputPathCheck` could be a workaround, but `tsc` doesn't allow that flag from the command line or tsconfig.json  (it's not in `optionDeclarations` in `commandLineParser.ts`)