Microsoft/TypeScript

`for (const x in #b)` is allowed

Open

#58.754 geöffnet am 3. Juni 2024

Auf GitHub ansehen
 (1 Kommentar) (1 Reaktion) (0 zugewiesene Personen)TypeScript (6.726 Forks)batch import
BugDomain: ParserHelp Wanted

Repository-Metriken

Stars
 (48.455 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 6T 17h) (9 gemergte PRs in 30 T)

Beschreibung

🔎 Search Terms

Private identifier, for...in

🕗 Version & Regression Information

  • This changed between versions 4.5.5 and 4.6.4

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.5.0-dev.20240603#code/MYGwhgzhAECC0G8BQ1oGIBGAKAlIlq0AZgPYBO0WwJAdhAC7RjQCWN6Geyh0Avgf35A

💻 Code

class A {
  #b() {
    for (const a in #b) {
    }
  }
}

🙁 Actual behavior

No errors

🙂 Expected behavior

Error: 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

Additional information about the issue

Noticed this while working on https://github.com/typescript-eslint/typescript-eslint/pull/9232. There's a very suspicious condition in code: https://github.com/microsoft/TypeScript/blob/5a4134470128a062a8297f404dfb3321f8f55798/src/compiler/checker.ts#L33699

    function checkGrammarPrivateIdentifierExpression(privId: PrivateIdentifier): boolean {
        if (!getContainingClass(privId)) {
            return grammarErrorOnNode(privId, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
        }

        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;
    }

I don't know what isForInStatement is supposed to do there. I was unable to find the commit that introduced this—git blame took me to #44648 but that didn't have this condition.

Contributor Guide