Report inferred type predicate inference fallback#3194
Report inferred type predicate inference fallback#3194jakebailey wants to merge 3 commits intomainfrom
Conversation
There was a problem hiding this comment.
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. |
internal/checker/nodebuilderimpl.go
Outdated
| returnTypeNode = b.pseudoTypeToNode(pt) | ||
| } | ||
| restore() | ||
| } else if typePredicate != nil && !b.ctx.suppressReportInferenceFallback { |
There was a problem hiding this comment.
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.
| } else if typePredicate != nil && !b.ctx.suppressReportInferenceFallback { | |
| } else if typePredicate != nil && signature.declaration != nil && signature.declaration.Type() == nil && !b.ctx.suppressReportInferenceFallback { |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.
| b.ctx.tracker.ReportInferenceFallback(signature.declaration) | |
| if signature.declaration != nil { | |
| b.ctx.tracker.ReportInferenceFallback(signature.declaration) | |
| } |
|
|
||
| export function isString(value: unknown) { | ||
| return typeof value === "string"; | ||
| } |
There was a problem hiding this comment.
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.
| } | |
| } | |
| export function isExplicitString(value: unknown): value is string { | |
| return typeof value === "string"; | |
| } |
Fixes #3193