Skip to content

Report inferred type predicate inference fallback#3194

Open
jakebailey wants to merge 3 commits intomainfrom
jabaile/inference-fallback-type-predicate
Open

Report inferred type predicate inference fallback#3194
jakebailey wants to merge 3 commits intomainfrom
jabaile/inference-fallback-type-predicate

Conversation

@jakebailey
Copy link
Member

Fixes #3193

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds --isolatedDeclarations coverage for inferred type predicate functions and updates the declaration/type node builder to report inference fallback when a signature’s return type is a type predicate.

Changes:

  • Added a new compiler test case for an inferred type guard under --isolatedDeclarations.
  • Added new reference baselines for the test (errors, JS/DTs emit, types, symbols).
  • Updated return-type serialization to report inference fallback when encountering a type predicate.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
testdata/tests/cases/compiler/isolatedDeclarationsTypePredicate.ts New test reproducing #3193 scenario.
testdata/baselines/reference/compiler/isolatedDeclarationsTypePredicate.errors.txt Expected TS9007 diagnostic baseline.
testdata/baselines/reference/compiler/isolatedDeclarationsTypePredicate.js Emit + .d.ts baseline for the new test.
testdata/baselines/reference/compiler/isolatedDeclarationsTypePredicate.types Type baseline showing inferred predicate typing.
testdata/baselines/reference/compiler/isolatedDeclarationsTypePredicate.symbols Symbol baseline for the new test.
internal/checker/nodebuilderimpl.go Reports inference fallback when serializing type predicate return types.

returnTypeNode = b.pseudoTypeToNode(pt)
}
restore()
} else if typePredicate != nil && !b.ctx.suppressReportInferenceFallback {
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReportInferenceFallback is triggered for any signature with a type predicate, including when the predicate is explicitly annotated (i.e. signature.declaration.Type() is a TypePredicateNode). That would incorrectly raise TS9007 under --isolatedDeclarations even though an explicit return type is present. Gate this report to only inferred predicates (e.g. when the declaration has no return type annotation) or implement reuse/matching for explicit predicate return types and only report when that reuse fails.

Suggested change
} else if typePredicate != nil && !b.ctx.suppressReportInferenceFallback {
} else if typePredicate != nil && signature.declaration != nil && signature.declaration.Type() == nil && !b.ctx.suppressReportInferenceFallback {

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about that... if there's an annotation, we surely won't even ever ask to build a type.

}
restore()
} else if typePredicate != nil && !b.ctx.suppressReportInferenceFallback {
b.ctx.tracker.ReportInferenceFallback(signature.declaration)
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReportInferenceFallback is called with signature.declaration without checking for nil. If serializeReturnTypeForSignature is ever invoked for a signature with a type predicate but no associated declaration, this will likely panic in the declaration emitter's tracker (it assumes a non-nil node). Add a nil guard (or choose a safer fallback node) before reporting.

Suggested change
b.ctx.tracker.ReportInferenceFallback(signature.declaration)
if signature.declaration != nil {
b.ctx.tracker.ReportInferenceFallback(signature.declaration)
}

Copilot uses AI. Check for mistakes.

export function isString(value: unknown) {
return typeof value === "string";
}
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test covers the missing-annotation case, but it doesn't assert the complementary behavior that an explicitly annotated type predicate return type (e.g. : value is string) should not produce TS9007 under --isolatedDeclarations. Adding a second function in this file with an explicit type predicate return type would prevent regressions where all type predicates get flagged.

Suggested change
}
}
export function isExplicitString(value: unknown): value is string {
return typeof value === "string";
}

Copilot uses AI. Check for mistakes.
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.

isolatedDeclarations does not flag potential type predicate funcs

2 participants