Skip to content

fix(tsconfig): apply later-wins semantics for extends array#1156

Merged
Boshen merged 1 commit into
mainfrom
fix-tsconfig-extends-array-last-wins
May 25, 2026
Merged

fix(tsconfig): apply later-wins semantics for extends array#1156
Boshen merged 1 commit into
mainfrom
fix-tsconfig-extends-array-last-wins

Conversation

@Boshen

@Boshen Boshen commented May 25, 2026

Copy link
Copy Markdown
Member

Summary

Per TypeScript spec, when extends is an array, later configurations override earlier ones. typescript-go implements this by accumulating into a result that each base overwrites in turn (applyExtendedConfigmergeCompilerOptions).

oxc-resolver's extend_tsconfig only fills None fields, so iterating forward made the first base set a value, blocking later bases from overriding it — first-wins instead of later-wins.

Fix: iterate extended_tsconfig_paths in reverse in both extend sites (load_tsconfig and the project-references extend_tsconfig). The last base now sets fields first; earlier bases see them set and skip; the child's own explicit fields (set before any extend) still win because they're populated before either loop runs.

Removes the #[ignore] on tsconfig_lookup::extends_array_last_wins (added in #1155) which now passes. The existing extends-multiple test still passes because it resolves via baseUrl fall-through, not via the order of inherited paths.

🤖 Generated with Claude Code

Per TypeScript spec, when `extends` is an array, later configurations
override earlier ones. typescript-go implements this by accumulating
into a result that each base overwrites in turn
(`applyExtendedConfig` + `mergeCompilerOptions`).

oxc-resolver's `extend_tsconfig` only fills `None` fields, so iterating
forward made the first base set a value, blocking later bases from
overriding it — first-wins instead of later-wins.

Fix: iterate `extended_tsconfig_paths` in reverse in both extend sites
(`load_tsconfig` and the project-references `extend_tsconfig`). The
last base now sets fields first; earlier bases see them set and skip;
the child's own explicit fields (set before any extend) still win
because they're populated before either loop runs.

Removes the `#[ignore]` on `tsconfig_lookup::extends_array_last_wins`
which now passes. Existing `extends-multiple` still passes because
that test resolves via `baseUrl` fall-through, not via the order of
inherited `paths`.
@codecov

codecov Bot commented May 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.34%. Comparing base (baf2d56) to head (0d81938).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1156   +/-   ##
=======================================
  Coverage   93.34%   93.34%           
=======================================
  Files          22       22           
  Lines        4177     4177           
=======================================
  Hits         3899     3899           
  Misses        278      278           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Boshen Boshen merged commit 3d8ed1f into main May 25, 2026
17 checks passed
@Boshen Boshen deleted the fix-tsconfig-extends-array-last-wins branch May 25, 2026 06:02
@oxc-guard oxc-guard Bot mentioned this pull request May 25, 2026
@codspeed-hq

codspeed-hq Bot commented May 25, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 13 untouched benchmarks
⏩ 5 skipped benchmarks1


Comparing fix-tsconfig-extends-array-last-wins (0d81938) with main (baf2d56)

Open in CodSpeed

Footnotes

  1. 5 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Boshen added a commit that referenced this pull request May 25, 2026
## 🤖 New release

* `oxc_resolver`: 11.19.1 -> 11.19.2
* `oxc_resolver_napi`: 11.19.1 -> 11.19.2

<details><summary><i><b>Changelog</b></i></summary><p>

## `oxc_resolver`

<blockquote>

##
[11.19.2](v11.19.1...v11.19.2)
- 2026-05-25

### <!-- 1 -->🐛 Bug Fixes

- *(tsconfig)* apply later-wins semantics for extends array
([#1156](#1156)) (by
@Boshen)
- *(tsconfig)* walk past a tsconfig that doesn't claim the file
([#1154](#1154)) (by
@Boshen)
- *(tsconfig)* let project references take priority over their parent
([#1151](#1151)) (by
@Boshen)
- *(tsconfig)* resolve `rootDirs` against the config that declared them
([#1150](#1150)) (by
@Boshen)
- *(tsconfig)* resolve `baseUrl` / `paths` against the canonical
tsconfig path
([#1148](#1148)) (by
@Boshen)
- strip query fragments when calling `find_tsconfig`
([#1147](#1147)) (by
@Boshen)
- avoid panic in resolve_file for parentless paths
([#1053](#1053)) (by
@Boshen)
- *(dts)* strip ./ prefix from package entry when matching typesVersions
([#1051](#1051)) (by
@Boshen)
- *(dts)* expand Declaration to TypeScript|Declaration for package entry
resolution
([#1050](#1050)) (by
@Boshen)
- *(dts)* prefer declaration extensions over JS in exports-resolved
paths ([#1047](#1047))
(by @Boshen)
- avoid wasm/wasi dead-code lint in NodePath
([#1043](#1043)) (by
@Boshen)
- *(napi)* replace panics with error returns to prevent WASM traps
([#1055](#1055)) (by
@Boshen)

### <!-- 2 -->🚜 Refactor

- remove clear_cache test that dynamically creates fixtures (by @Boshen)
- move resolve and misc fixtures into fixtures/integration (by @Boshen)
- replace ignored doctest with link to example (by @Boshen)
- consolidate fixture directories for better test file mapping (by
@Boshen)
- replace `url` crate with `percent-encoding`
([#1065](#1065)) (by
@Boshen)

### <!-- 4 -->⚡ Performance

- *(cache)* pack CachedPathImpl::meta into a CachedMeta byte
([#1144](#1144)) (by
@Boshen)
- *(cache)* store canonical path as Box<Path> instead of PathBuf
([#1143](#1143)) (by
@Boshen)
- *(alias)* fast-reject alias entries by cached first byte
([#1142](#1142)) (by
@Boshen)

### <!-- 6 -->🧪 Testing

- *(tsconfig)* port lookup scenarios from typescript-go
([#1155](#1155)) (by
@Boshen)
- add 28 tests to improve coverage (92% → 93%)
([#1082](#1082)) (by
@Boshen)

### Contributors

* @Boshen
* @renovate[bot]
</blockquote>



</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant