-
Notifications
You must be signed in to change notification settings - Fork 12.9k
fix(46246): Extending Class/Interface With a Primitive Throws a More Concise Error Report #49208
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
Conversation
This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise. |
Unless that named type is a union type or a mapped type. Or as error 2312 frames it:
|
Hey, thanks for the info. I accidentally made a bonus descriptive error for classes extending primitives: class foo extends number {} // An interface (SHOULD BE CLASS) cannot extend a primitive type like 'number'; An interface can only extend named types and classes. Couple quick questions:
|
No idea. I'm no member of the TypeScript team. I just saw the new error message you added and wanted to point that it's incorrect (or at least not always correct). |
…ypeScript into Extend-Primitive-Error Merging json
Thank you,
|
I'm following up on the review request, thank you @DanielRosenwasser |
@@ -95,7 +95,7 @@ gulp help # List the above commands. | |||
## Usage | |||
|
|||
```bash | |||
node built/local/tsc.js hello.ts | |||
node <repo-root>/built/local/tsc.js hello.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you revert the changes here and in package.json? They're not related to the fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, will do.
"category": "Error", | ||
"code": 18042 | ||
}, | ||
"A class cannot extend a primitive type like '{0}'. A class can only extend named object types.": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While you're adding class-specific errors, a separate error for when classes implement primitive types would be nice.
else if(meaning & SymbolFlags.Class) { | ||
error(errorLocation, Diagnostics.A_class_cannot_extend_a_primitive_type_like_0_A_class_can_only_extend_named_object_types, rawName); | ||
} | ||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you should return true unless one of the above errors was issued.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line 2503 if (isPrimitiveTypeName(name) && !(errorLocation.parent.parent.kind & ~SyntaxKind.HeritageClause))
This is our error check. If we are in this scope, there is an error, so we only need one return statement. The if/else checks if it's a class or interface and throws a respective error. After the error is called, we return true. Would you like to see the return within the inner scopes above, or is this okay? (It does need a default error, though)
if(meaning & SymbolFlags.Interface) { | ||
error(errorLocation, Diagnostics.An_interface_cannot_extend_a_primitive_type_like_0_An_interface_can_only_extend_named_object_types, rawName); | ||
} | ||
else if(meaning & SymbolFlags.Class) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A syntactic check (of errorLocation.parent.parent.parent
I think) is better. meaning
is the kind of symbol requested by name resolution.
Also you should probably check that all those parent nodes are defined.
I'll be picking this back up within the week. I would like to continue working on this and add the additional class error. Thank you for the feedback! |
@maross3 Do you want to keep working on this? Otherwise I'd like to close it to reduce the number of open PRs. |
fixes #46246
Example
Class:
Error:
A class cannot extend a primitive type like 'number'. A class can only extend named object types.
Interface:
Error:
An interface cannot extend a primitive type like 'number'. An interface can only extend named object types.
Notes:
runtests
passed on current branch.checkAndReportErrorForUsingTypeAsValue
checkAndReportErrorForExtendingPrimitiveType
Description
The approach was to check for extension of primitives directly before the ambiguous error message was thrown. This lead to making a new function.
I didn't add the code to the function
checkAndReportErrorForUsingTypeAsValue
because the intended error checking functionality was separate from evaluating the value for error checking.The new function
checkAndReportErrorForExtendingPrimitiveType
now handles checking heritage clause related errors in regards to classes extending primitives.In the code, we check if the current errorLocation's expected heritage clause was, in fact, a
SyntaxKind.HeritageClause
. A bitmask was used to check against the expected heritage clause:errorLocation.parent.parent.kind
. If it's a primitive name and a heritage clause, we throw a more descriptive error.This was my first contribution to any project of any size, so I would appreciate any feedback!