Repository: TypeScript
Issue: When relatively importing a `.d.ts` file in a declaration file, TypeScript loads a `.ts` file instead
Labels: Needs Investigation,Fix Available

### 🔎 Search Terms

- module resolution
- probing

### 🕗 Version & Regression Information

TypeScript 5.4.3

### ⏯ Playground Link

_No response_

### 💻 Code

```json
// package.json
{
  "name": "test4",
  "dependencies": {
    "@std/fs": "npm:@jsr/std__fs@^0.224.0"
  }
}
```

```json
// package-lock.json
{
  "name": "test4",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "dependencies": {
        "@std/fs": "npm:@jsr/std__fs@^0.224.0"
      }
    },
    "node_modules/@jsr/std__assert": {
      "version": "0.224.0",
      "resolved": "https://npm.jsr.io/~/8/@jsr/std__assert/0.224.0.tgz",
      "integrity": "sha512-2JTYGKyQ9Rb9NEalTJIN3LZ5NaDuoOpHesqP1+5sjjTXVYkzLgDoykjaFwWBJ+70YIg2Tctkj1xoaG0ga7tzsg==",
      "dependencies": {
        "@jsr/std__fmt": "^0.224.0",
        "@jsr/std__internal": "^0.224.0"
      }
    },
    "node_modules/@jsr/std__fmt": {
      "version": "0.224.0",
      "resolved": "https://npm.jsr.io/~/8/@jsr/std__fmt/0.224.0.tgz",
      "integrity": "sha512-rj0m00LslTlQJyXmkWe114v9aSbK81B33VcgIrYaaRuE7DTiFe6cebkNGQdAPQemLC4vRqiQMOZ247GdFFhk4g=="
    },
    "node_modules/@jsr/std__internal": {
      "version": "0.224.0",
      "resolved": "https://npm.jsr.io/~/8/@jsr/std__internal/0.224.0.tgz",
      "integrity": "sha512-pinRPGlSqi0qgFGDs1LUJ8vIe0p1jh6SIt2b02266a4OIO7RSTQiZNd21PV9UIFuJbaNTsskhGzqlN2ePvPU0Q==",
      "dependencies": {
        "@jsr/std__fmt": "^0.224.0"
      }
    },
    "node_modules/@jsr/std__path": {
      "version": "0.224.0",
      "resolved": "https://npm.jsr.io/~/8/@jsr/std__path/0.224.0.tgz",
      "integrity": "sha512-E8Nyv8dox8vR5wbA4FS7wMlSctZ6L1CVwshMrNLgFUqcCOE3VCvjKokgXs43sJEcq3w8aIY62j/mDxeFIOvwvA==",
      "dependencies": {
        "@jsr/std__assert": "^0.224.0"
      }
    },
    "node_modules/@std/fs": {
      "name": "@jsr/std__fs",
      "version": "0.224.0",
      "resolved": "https://npm.jsr.io/~/8/@jsr/std__fs/0.224.0.tgz",
      "integrity": "sha512-z7dnRgqDlgqnm9P0oJYiur0uFmKoQ5zOujbm5X+KwbJb6cnmpw7PrzMroq3PWy0kNOkGMLb0AU3IlENa+cVmTA==",
      "dependencies": {
        "@jsr/std__assert": "^0.224.0",
        "@jsr/std__path": "^0.224.0"
      }
    }
  }
}
```

```
$ npm i
```

```json
// tsconfig.json
{
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "bundler"
  }
}
```

```ts
// index.ts
import { walk } from "@std/fs/walk";
```


### 🙁 Actual behavior

```
$ tsc --explainFiles
node_modules/@std/fs/_create_walk_entry.ts:12:36 - error TS2503: Cannot find namespace 'Deno'.

12 export interface WalkEntry extends Deno.DirEntry {
                                      ~~~~

node_modules/@std/fs/_create_walk_entry.ts:22:16 - error TS2304: Cannot find name 'Deno'.

22   const info = Deno.statSync(path);
                  ~~~~

node_modules/@std/fs/_create_walk_entry.ts:25:5 - error TS2353: Object literal may only specify known properties, and 'name' does not exist in type 'WalkEntry'.

25     name,
       ~~~~

node_modules/@std/fs/_create_walk_entry.ts:33:60 - error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option.

33 export async function createWalkEntry(path: string | URL): Promise<WalkEntry> {
                                                              ~~~~~~~~~~~~~~~~~~

node_modules/@std/fs/_create_walk_entry.ts:37:22 - error TS2304: Cannot find name 'Deno'.

37   const info = await Deno.stat(path);
                        ~~~~

node_modules/@std/fs/_create_walk_entry.ts:40:5 - error TS2353: Object literal may only specify known properties, and 'name' does not exist in type 'WalkEntry'.

40     name,
       ~~~~

node_modules/@std/fs/walk.d.ts:1:32 - error TS2846: A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file './_create_walk_entry.js' instead?

1 import { type WalkEntry } from "./_create_walk_entry.d.ts";
                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

node_modules/@std/fs/walk.d.ts:99:73 - error TS2583: Cannot find name 'AsyncIterableIterator'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2018' or later.

99  */ export declare function walk(root: string | URL, {}?: WalkOptions): AsyncIterableIterator<WalkEntry>;
                                                                           ~~~~~~~~~~~~~~~~~~~~~

node_modules/@std/fs/walk.d.ts:100:130 - error TS2304: Cannot find name 'IterableIterator'.

100 /** Same as {@linkcode walk} but uses synchronous ops */ export declare function walkSync(root: string | URL, {}?: WalkOptions): IterableIterator<WalkEntry>;
                                                                                                                                     ~~~~~~~~~~~~~~~~

../../../../.config/yarn/global/node_modules/typescript/lib/lib.d.ts
  Default library for target 'es5'
../../../../.config/yarn/global/node_modules/typescript/lib/lib.es5.d.ts
  Library referenced via 'es5' from file '../../../../.config/yarn/global/node_modules/typescript/lib/lib.d.ts'
../../../../.config/yarn/global/node_modules/typescript/lib/lib.dom.d.ts
  Library referenced via 'dom' from file '../../../../.config/yarn/global/node_modules/typescript/lib/lib.d.ts'
../../../../.config/yarn/global/node_modules/typescript/lib/lib.webworker.importscripts.d.ts
  Library referenced via 'webworker.importscripts' from file '../../../../.config/yarn/global/node_modules/typescript/lib/lib.d.ts'
../../../../.config/yarn/global/node_modules/typescript/lib/lib.scripthost.d.ts
  Library referenced via 'scripthost' from file '../../../../.config/yarn/global/node_modules/typescript/lib/lib.d.ts'
../../../../.config/yarn/global/node_modules/typescript/lib/lib.decorators.d.ts
  Library referenced via 'decorators' from file '../../../../.config/yarn/global/node_modules/typescript/lib/lib.es5.d.ts'
../../../../.config/yarn/global/node_modules/typescript/lib/lib.decorators.legacy.d.ts
  Library referenced via 'decorators.legacy' from file '../../../../.config/yarn/global/node_modules/typescript/lib/lib.es5.d.ts'
node_modules/@jsr/std__path/basename.d.ts
  Imported via "@jsr/std__path/basename" from file 'node_modules/@std/fs/_create_walk_entry.ts' with packageId '@jsr/std__path/basename.d.ts@0.224.0'
node_modules/@jsr/std__path/normalize.d.ts
  Imported via "@jsr/std__path/normalize" from file 'node_modules/@std/fs/_create_walk_entry.ts' with packageId '@jsr/std__path/normalize.d.ts@0.224.0'
node_modules/@jsr/std__path/from_file_url.d.ts
  Imported via "@jsr/std__path/from-file-url" from file 'node_modules/@std/fs/_to_path_string.ts' with packageId '@jsr/std__path/from_file_url.d.ts@0.224.0'
node_modules/@std/fs/_to_path_string.ts
  Imported via "./_to_path_string.js" from file 'node_modules/@std/fs/_create_walk_entry.ts' with packageId '@jsr/std__fs/_to_path_string.ts@0.224.0'
node_modules/@std/fs/_create_walk_entry.ts
  Imported via "./_create_walk_entry.d.ts" from file 'node_modules/@std/fs/walk.d.ts' with packageId '@jsr/std__fs/_create_walk_entry.ts@0.224.0'
node_modules/@std/fs/walk.d.ts
  Imported via "@std/fs/walk" from file 'index.ts' with packageId '@jsr/std__fs/walk.d.ts@0.224.0'
index.ts
  Matched by default include pattern '**/*'

Found 9 errors in 2 files.

Errors  Files
     6  node_modules/@std/fs/_create_walk_entry.ts:12
     3  node_modules/@std/fs/walk.d.ts:1
```

From the `walk.d.ts` file (referenced specified in `package.json` `"types"` conditional export), a type is imported from `./_create_walk_entry.d.ts`. TypeScript however does not load `./_create_walk_entry.d.ts`, but instead loads `./_create_walk_entry.ts` (and then tries to check it) even though `./_create_walk_entry.d.ts` exists. Why?

The `.ts` files are included in the published package to enable "Go to source definition" for users. Is it really necessary to place all generated files into a separate directory?

### 🙂 Expected behavior

No `.ts` file to be loaded, because all specifiers (both in conditional exports, and in declaration files) reference `.d.ts` files.

This is especially the case because when `declaration: true` is specified, TypeScript will  by default place `.js` and `.d.ts` directly next to the `.ts` code. If you publish this to npm, it will not work.

### Additional information about the issue

_No response_