Description
🔎 Search Terms
There is a critical null pointer issue in TypeScript's incremental compilation builder system where state.affectedFilesIndex
is accessed with non-null assertion (!
) despite being defined as number | undefined
in the BuilderProgramState
interface.
incremental builder, affectedFilesIndex, null pointer, builder.ts, GH#18217
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about incremental compilation, builder state management, and null pointer access patterns
- The fix has been provided in PR Fixed (Critical null pointer bug) in incremental builder #61807
- This affects the current main branch
- Related to TODO comment:
// TODO: GH#18217
⏯ Playground Link
N/A - compiler issue
💻 Code
Problematic code locations:
src/compiler/builder.ts
line 643:let affectedFilesIndex = state.affectedFilesIndex!; // TODO: GH#18217
src/compiler/builder.ts
line 2147: Similar pattern with undefined access
Interface definition:
export interface BuilderProgramState extends BuilderState, ReusableBuilderProgramState {
/**
* Current index to retrieve affected file from
*/
affectedFilesIndex: number | undefined; // ← Can be undefined
}
🙁 Actual behavior
The code uses non-null assertion (!
) when accessing affectedFilesIndex
, which can cause runtime crashes when the value is actually undefined
.
🙂 Expected behavior
The code should properly handle the undefined
case using appropriate null-checking or default values.
Additional information about the issue
This issue also affects diagnostic property mappings between Diagnostic
and ReusableDiagnostic
types where property names differ (reportsDeprecated
vs reportDeprecated
).
Impact
- Potential runtime crashes during incremental builds
- Type safety violations
- Affects complex project builds with multiple file dependencies
Proposed Solution
I have a fix ready in PR #61807 that:
- Replaces
state.affectedFilesIndex!
withstate.affectedFilesIndex ?? 0
- Fixes diagnostic property mapping inconsistencies
- Maintains backward compatibility while improving type safety
Risk Assessment: Low risk - only affects error-prone access patterns without changing core functionality.