microsoft / microsoft/TypeScript

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

Open
#62,806 3 comments 0 reactions 1 assignee View on GitHub

@weswigham is already working on this.

Since Dec 9, 2025.

Needs Investigation
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
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. 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.

graph LR
  a --> b
  a --> c
  b --> c
// packages/a/src/index.ts

import { B } from "b";

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

export const c = b.c;
// packages/b/src/index.ts

import { C } from "c";

export interface B {
  readonly c: C;
}
// packages/c/src/index.ts

export type { C } from "./C";
export type { C2 as C2 } from "./C2";
// packages/c/src/C.ts

export interface C {
  readonly foo: "bar";
}
// 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.

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.

# 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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.