Skip to content

Add conditions to check for class extension or implementation of prim… #55712

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

Merged
merged 6 commits into from
Oct 26, 2023

Conversation

qwefgh90
Copy link
Contributor

fixes unresolved issues that discussed on #49208.

Example

Class implementing the primitive:

class C implements number { }
class C2 implements string { }
class C3 implements boolean { }

Actual behavior:

'number' only refers to a type, but is being used as a value here.
'string' only refers to a type, but is being used as a value here.
'boolean' only refers to a type, but is being used as a value here.

Improvement:

A class cannot implement a primitive type like 'number'; a class can only implement interfaces.
A class cannot implement a primitive type like 'string'; a class can only implement interfaces.
A class cannot implement a primitive type like 'boolean'; a class can only implement interfaces.

Class extending the primitive:

class C extends number { }
class C2 extends string { }
class C3 extends boolean { }

Actual behavior:

'number' only refers to a type, but is being used as a value here.
'string' only refers to a type, but is being used as a value here.
'boolean' only refers to a type, but is being used as a value here.

Improvement:

A class cannot extend a primitive type like 'number'; a class can only extend named types and classes.
A class cannot extend a primitive type like 'string'; a class can only extend named types and classes.
A class cannot extend a primitive type like 'boolean'; a class can only extend named types and classes.

Notes:

  • gulp runtests passed on current branch.
  • The errors related to implement weren't covered by current unit tests. I added a new test tests\cases\compiler\classImplementsPrimitive.ts to test classes implementing primitive types.
  • I updated a few unit tests to test for the error.
  • I made additional changes for some minor typos.

Description

PR #49208 was initially created to address issue #46246 along with some related problems.

However, that issue #46246 has been resolved by a different PR. So, PR #49208 wasn't merged and It was closed while leaving some issues that had been newly found and discussed in this PR, specifically related to incorrect error messages where classes extends or implements primitive types, as shown in the examples above.

To address these issue, I have made changes to the checkAndReportErrorForUsingTypeAsValue function, which has been responsible for these kinds of errors since #46357 was merged.

I have added new functions, isExtendedByClass and isImplementedByClass which determine if errorLocation 's grandparent contains SyntaxKind.ImplementsKeyword or SyntaxKind.ExtendsKeyword. If a condition evaluates to true, the relevant error message is emitted.

I would appreciate any feedback!

@typescript-bot typescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Sep 11, 2023
@typescript-bot
Copy link
Collaborator

This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise.

@DanielRosenwasser
Copy link
Member

The errors are no longer exactly correct. They should be

An interface cannot extend a primitive type like '{0}'. It can only extend other named object types.

A class cannot implement a primitive type like '{0}'. It can only extend other named object types.

A class cannot extend a primitive type like '{0}'. Classes can only extend constructable values.

"category": "Error",
"code": 2855
},
"A class cannot implement a primitive type like '{0}'. It can only extend other named object types.": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this message refer to 'implement' both times? Seems like it should but I'm not sure.

Suggested change
"A class cannot implement a primitive type like '{0}'. It can only extend other named object types.": {
"A class cannot implement a primitive type like '{0}'. It can only implement other named object types.": {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, that looks a typo. 'implement' would be better in this context.

class C implements number { }
class C2 implements string { }
class C3 implements boolean { }
class C4 implements Void { }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for this test; there's no type named Void.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching that.

class C3 implements boolean { }
class C4 implements Void { }
class C4a implements void {}
class C5 implements Null { }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

class C5 implements Null { }
class C5a implements null { }
class C6 implements undefined { }
class C7 implements Undefined { }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

Comment on lines 9 to 10
class C5a implements null { }
class C6 implements undefined { }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testing null and undefined doesn't feel relevant to this PR since the new errors don't apply. Can you grep for existing tests that have 'implements null/undefined'? If there aren't any, feel free to leave them here; otherwise, remove them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There aren't both. However, I would remove these cases because these tests aren't relevant to this PR as you said.

Comment on lines 13 to 17
enum E { A }
class C8 implements E { }

class C4a implements void {}
class C5a implements null { }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment for these; it's nice to have these tests, but if they're already in the test suite, you don't need to add them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to look up the case of class implementing enum. However there isn't any result found. this time, I would remove these cases because these tests aren't relevant to this PR

Copy link
Member

@andrewbranch andrewbranch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@andrewbranch andrewbranch requested a review from sandersn October 2, 2023 17:54
@andrewbranch
Copy link
Member

Sorry, looks like you’ll need to git merge main and fix the diagnostic message conflicts. Someone probably took one of the numbers you were using 🙈

@qwefgh90
Copy link
Contributor Author

qwefgh90 commented Oct 3, 2023

Thank you for letting me know. I did git rebase main to put my changes on the top of the latest commit. I stored old branch in case I made a mistake.

I just fixed the error numbers during the rebase. Is it okay to git rebase main? If not, I can merge with git merge main.

(edit)
I should have read the section about force-pushing. Thank you for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

5 participants