Repository navigation
Report an error for class declarations in statement position - #65005
Merged
Ryan Cavanaugh (RyanCavanaugh) merged 1 commit intoOct 29, 2026
Conversation
A class declaration used directly as the body of an if, else, loop or labeled statement is a syntax error at runtime, but was accepted without error. Report TS1156, as is already done for interface and type alias declarations. Fixes microsoft#22682
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are reported for the change that diagnoses class declarations used directly as statement bodies.
No open issues 🎉
What changed in this PR
Addresses #22682 by making the native TypeScript checker report TS1156 for class declarations used directly as statement bodies in TypeScript and JavaScript files.
Changes:
- Reuses the existing block-scope container check for class declarations.
- Adds regression coverage for invalid statement positions, valid declaration locations, and class expressions.
- Adds diagnostic, JavaScript emit, type, and symbol baselines.
| File | Description |
|---|---|
tsc/testdata/tests/cases/compiler/classDeclarationInStatementPosition.ts |
Tests invalid statement positions and unaffected valid cases. |
tsc/testdata/baselines/reference/compiler/classDeclarationInStatementPosition.types |
Records expected type information. |
tsc/testdata/baselines/reference/compiler/classDeclarationInStatementPosition.symbols |
Records expected symbol information. |
tsc/testdata/baselines/reference/compiler/classDeclarationInStatementPosition.js |
Records JavaScript emit for the regression test. |
tsc/testdata/baselines/reference/compiler/classDeclarationInStatementPosition.errors.txt |
Records expected diagnostics, including TS1156 in plain JavaScript. |
tsc/internal/checker/checker.go |
Rejects class declarations in disallowed statement positions. |
Review effort: Balanced
Contributor
Author
|
@microsoft-github-policy-service agree |
Member
|
Timon Gärtner (@TimonGaertner) this is an unusually good test, what model and reasoning effort were you using? |
Ryan Cavanaugh (RyanCavanaugh)
approved these changes
Oct 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #22682
A class declaration used directly as the body of an
if,else, loop, or labeled statement (for exampleif (cond) class C {}) is rejected by JavaScript engines with aSyntaxError, buttsccurrently accepts it without any error, in both.tsand plain.jsfiles.interfaceandtypedeclarations in the same position already report TS1156 ("... declarations can only be declared inside a block").This adds the same check to
checkClassDeclaration, reusingcontainerAllowsBlockScopedVariable, so the class case reports:Class expressions (
return class C {},x = class C {}) and class declarations in blocks, case clauses, namespaces, function bodies and at the top level are unaffected; the test covers these. TS1156 is already on the plain-JS diagnostic allowlist, so.jsfiles get the error too.Note: I limited this to
class, following the clarified repro in the issue.enumin the same position is valid TypeScript (just useless, as noted in the issue), so I left it alone; happy to add it if wanted.Test: new compiler test
classDeclarationInStatementPosition.ts; no existing baselines change.AI disclosure: I used Claude Code to help investigate the issue and write this change. I have reviewed and tested the result myself, understand it, and will handle the review discussion.