Skip to content

Project reference redirect uses wrong tsconfig when file belongs to multiple sub-projects (breaks customConditions/moduleSuffixes) #3106

@tian000

Description

@tian000

Bug Report

When a file is included in multiple tsconfig files within a composite project (e.g., both tsconfig.json and tsconfig.native.json), tsgo selects the wrong project reference redirect for the consumer's context. This causes internal module resolution to use the wrong customConditions and moduleSuffixes, resolving to incorrect platform-specific files.

tsc handles this correctly.

Minimal Reproduction

https://github.com/tian000/tsgo-project-ref-redirect-bug

git clone https://github.com/tian000/tsgo-project-ref-redirect-bug.git
cd tsgo-project-ref-redirect-bug

# tsc — passes ✓
tsc -b tsconfig.json

# tsgo — fails ✗
tsgo -b tsconfig.json
# app.ts(9,7): error TS2322: Type '"web"' is not assignable to type '"native"'.

Setup

A consumer app references a package (pkg) that has two tsconfigs:

  • pkg/tsconfig.json (web) — include: ["**/*"], no customConditions, references tsconfig.native.json
  • pkg/tsconfig.native.json (native) — customConditions: ["react-native"], moduleSuffixes: [".native", ""]

The package has platform-specific entry points via package.json exports:

{ "react-native": "./index.native.ts", "types": "./index.ts", "default": "./index.ts" }

The consumer uses customConditions: ["react-native"] and references pkg (which resolves to pkg/tsconfig.json).

Expected behavior (tsc)

tsc --traceResolution shows:

Resolving module './src/util' from 'pkg/index.native.ts'.
Resolving in CJS mode with conditions 'import', 'types', 'react-native'.
→ resolved to pkg/src/util.native.ts  ✓

Actual behavior (tsgo)

tsgo --traceResolution shows:

Resolving module './src/util' from 'pkg/index.native.ts'.
Using compiler options of project reference redirect 'pkg/tsconfig.json'.
Resolving in CJS mode with conditions 'import', 'types'.
→ resolved to pkg/src/util.ts  ✗

Root cause

pkg/index.native.ts is included in both tsconfigs — tsconfig.json matches it via "include": ["**/*"], and tsconfig.native.json explicitly includes it. When the consumer imports through this file, tsgo picks pkg/tsconfig.json (web, no customConditions) as the project reference redirect instead of pkg/tsconfig.native.json (native, with customConditions and moduleSuffixes).

tsc correctly uses tsconfig.native.json's compiler options for files that belong to the native sub-project, resulting in the react-native condition being applied to internal imports.

Real-world impact

This blocks tsgo adoption in monorepos with platform-specific tsconfigs — a standard pattern in React Native projects. In our monorepo (~11K TS files, 125 packages), this causes 772 type errors in the mobile app because all internal imports within referenced packages resolve to web types instead of native types, even though the entry points resolve correctly.

Version

@typescript/native-preview 7.0.0-dev.20260314.1
typescript 5.5.4 (for tsc comparison)

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions