Repository: TypeScript
Issue: if tsconfig.json contains paths section, generated declaration for implicit type uses wrong dynamic import
Labels: Bug,Domain: Declaration Emit

# Bug Report

As you know, sometimes generated .d.ts files will use dynamic import syntax to reference types that were implied, e.g. `function foo(): import("otherfile").sometype`.

But if, at compile time, `"otherfile"` was resolved by using the `"paths"` array in tsconfig.json, then the generated type signature will be wrong. It will contain a relative path (often starting with "..") that's relative to the location of the _source_ file, not relative to the location of the generated .d.ts file.

I'm pretty sure the right behavior here would be to use the exact same string that was used in the `import` statement, rather than a relative path.

### 🔎 Search Terms

dynamic import dts file paths

### 🕗 Version & Regression Information

This changed between versions 3.1.0-dev.20180721 and 3.1.0-dev.20180724 (quite a long time ago!)

### ⏯ Playground Link

This repro requires multiple files, so I tried to use the TypeScript Workbench, but it doesn't seem to support tsconfig's `"paths"` option. (I filed a separate [bug](https://github.com/microsoft/TypeScript-Website/issues/1555) for that.) So here's a [zip](https://github.com/microsoft/TypeScript/files/5941747/example.zip) with the code.

### 💻 Code

tsconfig.json — notice the "paths" section:
```json
{
  "compilerOptions": {
    "declaration": true,
    "outDir": "out/a/b/c",
    "baseUrl": "src",
    "paths": { "*": [ "*", "../lib/*" ] }
  },
  "files": [
    "src/bad.ts",
    "src/good.ts"
  ]
}
```

src/good.ts:
```ts
import { libFunc, LibInterface } from "mylib";

// The generated .d.ts file will not need a dynamic import, because we
// have already explicitly imported the type of someValue (LibInterface).
export const someValue = libFunc();
```

src/bad.ts:
```ts
import { libFunc } from "mylib";

// The generated .d.ts file will use a dyanamic import(...), because we
// have not imported the type of someValue (LibInterface).
export const someValue = libFunc();
```

lib/mylib.ts:
```ts
export interface LibInterface {}

export function libFunc(): LibInterface;
```

### 🙁 Actual behavior

After compiling, `out/a/b/c/good.d.ts` looks correct: It explicitly imports from "mylib":

```ts
import { LibInterface } from "mylib";
export declare const someValue: LibInterface;
```

However, `out/a/b/c/bad.d.ts`, which uses a dynamic import (as it should), has the wrong import path:

```ts
export declare const someValue: import("../lib/mylib").LibInterface;
```

The reasons this is wrong are:

* The source file (src/bad.ts) imported from "mylib", so the generated file should use the same path, without changes.
* The relative path that's used is not relative to the location of the generated .d.ts file.
* Even if it was correctly adjusted to the location of the generated .d.ts file, that would still be the wrong thing to do, I think. I think TypeScript import paths are supposed to match the import/require statements that are written to the JavaScript file. In this case, a/b/c/bad.js has the correct `require("mylib")`, not `require("../lib/mylib")`.

### 🙂 Expected behavior

The generated out/a/b/c/bad.d.ts should have `import("mylib")`:

```ts
export declare const someValue: import("mylib").LibInterface;
```

That way,

* The import statement matches the one from the original TypeScript file.
* This .d.ts file can be used in any project that is appropriate set up to be able to find `mylib`.