Fix private identifier fields generating errors in class expression declarations#62155
Fix private identifier fields generating errors in class expression declarations#62155
Conversation
Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
src/compiler/checker.ts
Outdated
| if (getDeclarationModifierFlagsFromSymbol(propertySymbol) & (ModifierFlags.Private | ModifierFlags.Protected) && context.tracker.reportPrivateInBaseOfClassExpression) { | ||
| context.tracker.reportPrivateInBaseOfClassExpression(unescapeLeadingUnderscores(propertySymbol.escapedName)); | ||
| } | ||
| // Skip ECMAScript private identifier fields (e.g., #field) in class expression type literals |
There was a problem hiding this comment.
Nope. This should be an error here, like a private. This is also much more verbose than needed. Try this instead:
| // Skip ECMAScript private identifier fields (e.g., #field) in class expression type literals | |
| if (isPrivateIdentifierSymbol(propertySymbol) && context.tracker.reportPrivateInBaseOfClassExpression) { | |
| context.tracker.reportPrivateInBaseOfClassExpression(idText((propertySymbol.valueDeclaration! as NamedDeclaration).name! as PrivateIdentifier)); | |
| } |
There was a problem hiding this comment.
Applied your suggestion! The implementation now uses isPrivateIdentifierSymbol and generates the same error as traditional private/protected fields instead of silently skipping them. This makes the behavior much more consistent and provides proper error reporting. Commit: b8ca24c
…class expressions Co-authored-by: weswigham <2932786+weswigham@users.noreply.github.com>
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a regression in TypeScript 5.9 where ECMAScript private fields (#field) in class expressions were silently excluded from declaration files, while traditional private/protected fields properly generated error messages. The fix ensures consistent error reporting for both types of private members in exported anonymous class types.
Key changes:
- Added proper error reporting for ECMAScript private identifier fields in class expressions
- Updated the type checker to use
isPrivateIdentifierSymbol()for reliable detection - Ensured both traditional and ECMAScript private fields generate the same TS4094 error
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/compiler/checker.ts |
Added error reporting logic for ECMAScript private identifier fields in class expressions |
tests/cases/compiler/privateFieldsInClassExpressionDeclaration.ts |
New test case covering both instance and static private fields |
tests/baselines/reference/privateFieldsInClassExpressionDeclaration.errors.txt |
Expected error output showing consistent TS4094 errors for all private fields |
tests/baselines/reference/privateFieldsInClassExpressionDeclaration.js |
Expected JavaScript compilation output |
tests/baselines/reference/privateFieldsInClassExpressionDeclaration.types |
Expected type information output |
tests/baselines/reference/privateFieldsInClassExpressionDeclaration.symbols |
Expected symbol information output |
This PR fixes a regression introduced in TypeScript 5.9 where private fields using ECMAScript syntax (
#field) were being silently excluded from class expression type literals in declaration files, while traditionalprivate/protectedfields generated proper error messages.Issue
When compiling a class expression with private fields to a declaration file, the behavior was inconsistent:
This inconsistency meant that ECMAScript private fields could potentially slip through without proper validation.
Root Cause
The
createTypeNodesFromResolvedTypefunction inchecker.tshad inconsistent handling for class expressions converted to type literals (WriteClassExpressionAsTypeLiteralflag):private/protectedfields: Generated error but continued processingcontinueSolution
Updated the implementation to treat both types of private fields consistently by:
isPrivateIdentifierSymbol()for reliable detection of ECMAScript private fieldsResult
Both types of private fields now generate consistent error messages, ensuring:
The fix maintains existing behavior for traditional private fields while bringing ECMAScript private fields in line with the same error reporting standards.
Fixes #62153.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.