Commit fd140b4
fix(bundling): skip unnecessary type-check in TS Solution Setup when skipTypeCheck is true (#34493)
## Current Behavior
In TS Solution Setup, the esbuild executor forces `runTypeCheck` even
when `skipTypeCheck: true` and `declaration: false`, due to the `||
options.isTsSolutionSetup` condition in `esbuild.impl.ts` (lines 139-140
and 195).
When `declaration: false`, this type check runs in `noEmit` mode with
`ignoreDiagnostics: true` — making it **completely pointless** (no
declarations emitted, no diagnostics reported). Its only observable
effect is writing a poisoned 19-byte tsbuildinfo file that causes race
conditions with `tsc --build`.
## Expected Behavior
When `skipTypeCheck: true` and `declaration: false`, the esbuild
executor should not run type checking at all. The `isTsSolutionSetup`
override should only force type checking when declarations actually need
to be generated.
## Fix
### Primary: Skip unnecessary type check (`esbuild.impl.ts`)
```diff
// Non-watch mode (line 195)
- if (!options.skipTypeCheck || options.isTsSolutionSetup) {
+ if (!options.skipTypeCheck || (options.isTsSolutionSetup && options.declaration)) {
// Watch mode (lines 139-140)
- options.isTsSolutionSetup
+ (options.isTsSolutionSetup && options.declaration)
```
Only force type checking in TS Solution Setup when declarations need to
be generated. This eliminates the pointless type check entirely.
### Defense-in-depth: Prevent tsbuildinfo in `noEmit` mode
(`run-type-check.ts`)
```diff
- : { noEmit: true };
+ : { noEmit: true, composite: false };
```
Setting `composite: false` alongside `noEmit: true` prevents TypeScript
from writing tsbuildinfo files, protecting against this class of bug
from any caller of `runTypeCheck`.
## Why This is Safe
| Scenario | Before | After |
|----------|--------|-------|
| `skipTypeCheck: false`, `declaration: false`, `isTsSolutionSetup:
true` | Runs type check (noEmit) | Still runs (`!false \|\| ...` = true)
|
| `skipTypeCheck: false`, `declaration: true`, `isTsSolutionSetup: true`
| Runs type check (emitDeclarationOnly) | Still runs |
| `skipTypeCheck: true`, `declaration: true`, `isTsSolutionSetup: true`
| normalize.ts overrides skipTypeCheck to false; runs type check | Still
runs (same normalization) |
| **`skipTypeCheck: true`, `declaration: false`, `isTsSolutionSetup:
true`** | **Runs pointless type check (noEmit + ignoreDiagnostics),
writes poisoned tsbuildinfo** | **Skipped entirely** |
The only behavior change is in the last row — the case where the type
check was doing nothing useful but causing harm.
## Related Issue(s)
Fixes #34492
---------
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
(cherry picked from commit bdeeb03)1 parent 72a4ba3 commit fd140b4
2 files changed
Lines changed: 6 additions & 3 deletions
File tree
- packages
- esbuild/src/executors/esbuild
- js/src/utils/typescript
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
137 | 137 | | |
138 | 138 | | |
139 | 139 | | |
140 | | - | |
| 140 | + | |
141 | 141 | | |
142 | 142 | | |
143 | 143 | | |
| |||
192 | 192 | | |
193 | 193 | | |
194 | 194 | | |
195 | | - | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
196 | 199 | | |
197 | 200 | | |
198 | 201 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
140 | 140 | | |
141 | 141 | | |
142 | 142 | | |
143 | | - | |
| 143 | + | |
144 | 144 | | |
145 | 145 | | |
146 | 146 | | |
| |||
0 commit comments