diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 941d14bd1f530..cf15876bef438 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28235,12 +28235,18 @@ namespace ts { if (!getContainingClass(privId)) { return grammarErrorOnNode(privId, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); } - if (!isExpressionNode(privId)) { - return grammarErrorOnNode(privId, Diagnostics.Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression); - } - if (!getSymbolForPrivateIdentifierExpression(privId)) { - return grammarErrorOnNode(privId, Diagnostics.Cannot_find_name_0, idText(privId)); + + if (!isForInStatement(privId.parent)) { + if (!isExpressionNode(privId)) { + return grammarErrorOnNode(privId, Diagnostics.Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression); + } + + const isInOperation = isBinaryExpression(privId.parent) && privId.parent.operatorToken.kind === SyntaxKind.InKeyword; + if (!getSymbolForPrivateIdentifierExpression(privId) && !isInOperation) { + return grammarErrorOnNode(privId, Diagnostics.Cannot_find_name_0, idText(privId)); + } } + return false; } diff --git a/tests/baselines/reference/privateNameInInExpression.errors.txt b/tests/baselines/reference/privateNameInInExpression.errors.txt index d4ba5f81e9fdc..514d2a85e84a6 100644 --- a/tests/baselines/reference/privateNameInInExpression.errors.txt +++ b/tests/baselines/reference/privateNameInInExpression.errors.txt @@ -1,15 +1,13 @@ tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts(21,29): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts(23,19): error TS2304: Cannot find name '#fiel'. tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts(23,19): error TS2339: Property '#fiel' does not exist on type 'any'. tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts(25,20): error TS1451: Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression -tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts(27,14): error TS1451: Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts(27,14): error TS2406: The left-hand side of a 'for...in' statement must be a variable or a property access. tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts(29,23): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'boolean'. tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts(43,27): error TS2531: Object is possibly 'null'. tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts(114,12): error TS18016: Private identifiers are not allowed outside class bodies. -==== tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts (9 errors) ==== +==== tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts (7 errors) ==== class Foo { #field = 1; static #staticField = 2; @@ -36,8 +34,6 @@ tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.t const b = #fiel in v; // Bad - typo in privateID ~~~~~ -!!! error TS2304: Cannot find name '#fiel'. - ~~~~~ !!! error TS2339: Property '#fiel' does not exist on type 'any'. const c = (#field) in v; // Bad - privateID is not an expression on its own @@ -46,8 +42,6 @@ tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.t for (#field in v) { /**/ } // Bad - 'in' not allowed ~~~~~~ -!!! error TS1451: Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression - ~~~~~~ !!! error TS2406: The left-hand side of a 'for...in' statement must be a variable or a property access. for (let d in #field in v) { /**/ } // Bad - rhs of in should be a object/any