TypeScript for (const x in #b) is allowed

5fjcxozz  于 6个月前  发布在  TypeScript
关注(0)|答案(1)|浏览(49)

🔎 搜索词

私有标识符,用于...in

🕗 版本与回归信息

  • 在版本4.5.5和4.6.4之间发生了变化

⏯ Playground链接

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

💻 代码

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

🙁 实际行为

无错误

🙂 预期行为

错误: 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

关于问题的附加信息

在处理 typescript-eslint/typescript-eslint#9232 时注意到了一个非常可疑的条件。代码位于: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;
    }

我不知道 isForInStatement 在那里应该做什么。我无法找到引入此条件的提交——git blame带我到了 #44648 ,但那没有这个条件。

bttbmeg0

bttbmeg01#

已修复bug #58798,似乎在修复bug #46824时引入了一些逻辑。

在这里的一些想法:首先进入*getContainingClass()逻辑,然后检查它是否在for-in块中,并且privId是for-in的初始化部分,如果是,则会被checkForInStatement()捕获。
接下来进入
isExpressionNode()*逻辑,这将只允许privId成为In表达式的左侧,这样就可以使用Error Diagnosis解决for-in块的右侧问题。
在这些逻辑之后,我们可以确保只有In表达式中的privId出现,然后我们检查它的声明。

相关问题