Skip to content

Infer void for statement-less function bodies in isolatedDeclarations syntactic inference - #4418

Open
Wesley Wigham (weswigham) wants to merge 3 commits into
microsoft:mainfrom
weswigham:infer-void-returns-in-ID
Open

Infer void for statement-less function bodies in isolatedDeclarations syntactic inference#4418
Wesley Wigham (weswigham) wants to merge 3 commits into
microsoft:mainfrom
weswigham:infer-void-returns-in-ID

Conversation

@weswigham

Copy link
Copy Markdown
Member

Per discussion in today's design meeting, pending any objections from the community. Since we no longer infer any for statementless function bodies in JS, we always, uniformly, infer void for these in the checker - making it a no-brainer to do the inference syntactically and avoid an isolatedDeclarations error requiring an explicit : void in the common case of an empty/noop function/method.

We'll move this to the 7.1 milestone once we have one~

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates the isolatedDeclarations syntactic inference path to treat statement-less (empty) function bodies as returning void, aligning with the checker’s behavior and reducing spurious “explicit return type required” diagnostics for empty/no-op functions.

Changes:

  • Added a void pseudo-type (PseudoTypeKindVoid/PseudoTypeVoid) and mapped it through the node/type builders.
  • Updated pseudo-checker return-type inference to return void for empty block bodies.
  • Refreshed a large set of isolated-declarations diagnostic baselines to reflect the new inference behavior (notably removing TS9007 in these cases).
  • Updated the fourslash “known failing tests” list to include additional failures.

Reviewed changes

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

Show a summary per file
File Description
internal/pseudochecker/type.go Adds a new PseudoTypeKindVoid and PseudoTypeVoid singleton.
internal/pseudochecker/lookup.go Returns PseudoTypeVoid for empty block-bodied functions during single-return inference.
internal/checker/pseudotypenodebuilder.go Maps PseudoTypeKindVoid to void type nodes and to the checker’s voidType.
internal/fourslash/_scripts/failingTests.txt Adds newly failing code-fix fourslash tests to the skip list.
testdata/baselines/reference/submoduleTriaged/compiler/isolatedDeclarationErrorsReturnTypes.errors.txt.diff Baseline updates reflecting changed isolated-declarations diagnostics (TS9007→other outcomes).
testdata/baselines/reference/submoduleTriaged/compiler/isolatedDeclarationErrorsExpandoFunctions.errors.txt.diff Baseline updates reflecting changed diagnostics for expando-function scenarios.
testdata/baselines/reference/submoduleTriaged/compiler/isolatedDeclarationErrorsClasses.errors.txt.diff Baseline updates removing method-return-type requirements in some empty-body cases.
testdata/baselines/reference/submoduleTriaged/compiler/isolatedDeclarationErrors.errors.txt.diff Baseline updates reflecting fewer TS9007 diagnostics for empty functions.
testdata/baselines/reference/submodule/compiler/isolatedDeclarationLazySymbols.errors.txt.diff Baseline diff updates reflecting removed TS9007 for empty exported function.
testdata/baselines/reference/submodule/compiler/isolatedDeclarationLazySymbols.errors.txt Baseline updates reflecting removed TS9007 for empty exported function.
testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsReturnTypes.errors.txt Baseline updates reflecting new diagnostic set in return-type-related fixtures.
testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsObjects.errors.txt.diff Baseline diff updates reflecting removed TS9008 for empty methods in object literals.
testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsObjects.errors.txt Baseline updates reflecting removed TS9008 for empty methods in object literals.
testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsFunctionDeclarations.errors.txt.diff Baseline diff updates reflecting removed TS9007 for empty exported function decl.
testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsFunctionDeclarations.errors.txt Baseline updates reflecting removed TS9007 for empty exported function decl.
testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsExpandoFunctions.errors.txt Baseline updates reflecting removed TS9007 for the top-level empty exported function.
testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsClasses.errors.txt Baseline updates reflecting removed TS9008 for empty method bodies in classes.
testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrors.errors.txt Baseline updates reflecting removed TS9007 for const x = () => {}-style empty functions.

Comment on lines 227 to 232
body := fn.Body()
if ast.IsBlock(body) {
if len(body.Statements()) == 0 {
return PseudoTypeVoid
}
ast.ForEachReturnStatement(body, func(stmt *ast.Node) bool {
Comment on lines +64 to +66
TestCodeFixMissingTypeAnnotationOnExports11
TestCodeFixMissingTypeAnnotationOnExports16
TestCodeFixMissingTypeAnnotationOnExports22_formatting
Comment on lines +70 to +73
TestCodeFixMissingTypeAnnotationOnExports28_long_types
TestCodeFixMissingTypeAnnotationOnExports33_methods
TestCodeFixMissingTypeAnnotationOnExports43_expando_functions_2
TestCodeFixMissingTypeAnnotationOnExports46_decorators_experimental
@RyanCavanaugh

Copy link
Copy Markdown
Member

Looks OK, fix merge conflicts?

@andrewbranch

Copy link
Copy Markdown
Member

When we talked about this at the design meeting, it was suggested/remembered at the very end of the meeting that we probably didn't do this originally in order to give us room in the future to make design changes around microsoft/TypeScript#42709 without breaking third-party isolatedDeclarations emitters.

@weswigham

Wesley Wigham (weswigham) commented Jul 15, 2026

Copy link
Copy Markdown
Member Author

Yeah, except if we change that inference, we'd just change the isolatedDeclarations inference rule to match. It's not really any worse for a 3rd party emitter than if we, say, add a new syntax construct type kind. I don't think it'd preclude us from changing anything there (however unlikely that is).

@RyanCavanaugh Ryan Cavanaugh (RyanCavanaugh) added the Unmigrated PR This PR was open at the time of the repo move back to TypeScript label Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Unmigrated PR This PR was open at the time of the repo move back to TypeScript

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants