microsoft / microsoft/TypeScript

Self-referencing causes non-portable inferred types (TS2742) false positive

Ouverte
#62,806 3 commentaires 0 réactions 1 personne assignée Voir sur GitHub

@weswigham y travaille déjà.

Depuis le 9/12/2025.

Needs Investigation
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

### 🔎 Search Terms

- The inferred type of '...' cannot be named without a reference to '...'. This is likely not portable. A type annotation is necessary.
- TS2742
- Project reference redirect
- Self-reference
- Build mode
- Watcher

### 🕗 Version & Regression Information

Versions 4.7 - 5.9.3.

I've reproduced this in TypeScript 4.7.2, which is when [self-referencing was first announced as a feature](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#packagejson-exports-imports-and-self-referencing). This bug appears on the latest version of TypeScript at the time of writing (i.e. 5.9.3).

### ⏯ Playground Link

This issue requires multiple NPM packages. Small repro at https://github.com/gluxon/typescript-portability-error-false-positive-due-to-self-import

### 💻 Code

I've set up a repro at https://github.com/gluxon/typescript-portability-error-false-positive-due-to-self-import.

The code below is from the repro above and should match exactly. The TypeScript for the repro itself is only ~16 lines of code. In these packages, package `a` depends on `b` + `c`, and package `b` depends on `c`.

```mermaid
graph LR
a --> b
a --> c
b --> c
```

```ts
// packages/a/src/index.ts

import { B } from "b";

const b: B = {
c: { foo: "bar" },
};

export const c = b.c;
```

```ts
// packages/b/src/index.ts

import { C } from "c";

export interface B {
readonly c: C;
}
```

```ts
// packages/c/src/index.ts

export type { C } from "./C";
export type { C2 as C2 } from "./C2";
```

```ts
// packages/c/src/C.ts

export interface C {
readonly foo: "bar";
}
```

```ts
// packages/c/src/C2.ts

// 🚨 This self-reference causes the non-portable type false positive. 🚨
// Importing from "./C" instead of "c" fixes the issue.
import { C } from "c";

export type C2 = C;
```

### 🙁 Actual behavior

When running `tsc` with build mode, a false positive error is shown.

```console
tsc --build --verbose packages/a/tsconfig.json
```

```
[8:40:22 PM] Building project '/Volumes/git/typescript-false-positive-non-portable-watcher-error/packages/a/tsconfig.json'...

packages/a/src/index.ts:7:14 - error TS2742: The inferred type of 'c' cannot be named without a reference to '../node_modules/c/src'. This is likely not portable. A type annotation is necessary.

7 export const c = b.c;
~
```

The error above should not happen since:

1. Running `tsc` without the build flag does not show this issue. (See "_Expected Behavior_" below.)
2. The portability error is non-sensical. It's looking for a reference to package `c`'s source code in `../node_modules/c/src` rather than its built `.d.ts` files. I've narrowed this to a bug with project reference redirects.
3. The portability error happens even when `c` is a dependency of `a`.

### 🙂 Expected behavior

Running `tsc` without the `--build` flag results in a successful compilation of package `a`.

```console
# Compile manually in topological order.
tsc -p packages/c/tsconfig.json
tsc -p packages/b/tsconfig.json
tsc -p packages/a/tsconfig.json
```

### Additional information about the issue

_No response_

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.