Skip to content

Some private identifier errors are duplicated and uninformative #46824

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sandersn opened this issue Nov 16, 2021 · 5 comments · Fixed by #47116
Closed

Some private identifier errors are duplicated and uninformative #46824

sandersn opened this issue Nov 16, 2021 · 5 comments · Fixed by #47116
Labels
Bug A bug in TypeScript Good First Issue Well scoped, documented and has the green light Help Wanted You can do this
Milestone

Comments

@sandersn
Copy link
Member

From privateNameInInExpression.errors.txt:

            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'.
            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.

Expected: One error on each line of code: "Cannot find name '#fiel'" and "The left-hand side of a 'for...in' statement must be a variable or property access."
Actual: Two errors on each line.

The cause is that checkGrammarPrivateIdentifierExpression does not check whether other errors might apply. From my most recent read of it, I think only the first error is actually valuable, and that the "Cannot find name '#fiel'" error can be issued elsewhere. It's not really a grammatical error in any case -- it's likely just issued there because the ES spec refers to these errors as syntactic.

@sandersn sandersn added Bug A bug in TypeScript Good First Issue Well scoped, documented and has the green light Help Wanted You can do this labels Nov 16, 2021
@sandersn sandersn added this to the Backlog milestone Nov 16, 2021
@Andrewnt219
Copy link
Contributor

Hi @sandersn, can I try to solve this one?

@sandersn
Copy link
Member Author

sandersn commented Dec 6, 2021

Go ahead; let me know if you need any help.

@Andrewnt219
Copy link
Contributor

Andrewnt219 commented Dec 9, 2021

Sorry, it took me a while to understand the setup and flow of the project.

From the issue, I assume you want to remove the "Cannot find name '#fiel'" when there is:
"The left-hand side of a 'for...in' statement must be a variable or property access." or
"Private identifiers are not allowed outside class bodies.".

From what I understand, the checkGrammarPrivateIdentifierExpression has 3 checks matching the 3 errors above, and it is only called when the expression syntax is private. So I cannot remove any of those if check because it affects other cases, but rather find a way to show only one of them in the case of multiple privateName errors?

// Code reference

function checkGrammarPrivateIdentifierExpression(privId: PrivateIdentifier): boolean {
    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));
    }
    return false;
}

@sandersn
Copy link
Member Author

Having thought about it a little more, I think I'd like to see

"Property '#fiel' does not exist on type 'any'.

for the first error and

The left-hand side of a 'for...in' statement must be a variable or a property access.

for the second. For the first error, the check for "cannot find name {0}" in checkGrammarPrivateIdentifierExpression needs to also check that privId's parent isn't an in expression. In the same way, the check for "Private identifiers are only allowed in class bodies" should also check that privId's parent isn't a for...in statement. That should avoid the duplicated errors.

@Andrewnt219
Copy link
Contributor

Thanks, it's pretty clear now. I'll try to send a PR tomorrow.

sandersn added a commit that referenced this issue Dec 17, 2021
Conflict between #47018 and #46824, both of which changed the behaviour of private fields.
sandersn added a commit that referenced this issue Dec 17, 2021
Conflict between #47018 and #46824, both of which changed the behaviour of private fields.
mprobst pushed a commit to mprobst/TypeScript that referenced this issue Jan 10, 2022
Conflict between microsoft#47018 and microsoft#46824, both of which changed the behaviour of private fields.
bernard-wang added a commit to bernard-wang/TypeScript that referenced this issue Jun 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Good First Issue Well scoped, documented and has the green light Help Wanted You can do this
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants