-
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
Changes from all commits
db2269c
ba102bc
d8a7755
ccc6aa1
2f7204e
9a7584e
301cf68
46c864f
b27a7bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2180,6 +2180,7 @@ namespace ts { | |
!checkAndReportErrorForExtendingInterface(errorLocation) && | ||
!checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) && | ||
!checkAndReportErrorForExportingPrimitiveType(errorLocation, name) && | ||
!checkAndReportErrorForExtendingPrimitiveType(errorLocation, name, meaning) && | ||
!checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) && | ||
!checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) && | ||
!checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) { | ||
|
@@ -2497,6 +2498,22 @@ namespace ts { | |
return false; | ||
} | ||
|
||
function checkAndReportErrorForExtendingPrimitiveType(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean { | ||
if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule)) { | ||
if (isPrimitiveTypeName(name) && !(errorLocation.parent.parent.kind & ~SyntaxKind.HeritageClause)) { | ||
const rawName = unescapeLeadingUnderscores(name); | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. A syntactic check (of Also you should probably check that all those parent nodes are defined. |
||
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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Line 2503 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) |
||
} | ||
} | ||
return false; | ||
} | ||
|
||
function maybeMappedType(node: Node, symbol: Symbol) { | ||
const container = findAncestor(node.parent, n => | ||
isComputedPropertyName(n) || isPropertySignature(n) ? false : isTypeLiteralNode(n) || "quit") as TypeLiteralNode | undefined; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7356,5 +7356,13 @@ | |
"A 'return' statement cannot be used inside a class static block.": { | ||
"category": "Error", | ||
"code": 18041 | ||
}, | ||
"An interface cannot extend a primitive type like '{0}'. An interface can only extend named object types.": { | ||
"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 commentThe 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. |
||
"category": "Error", | ||
"code": 18043 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
tests/cases/compiler/errorLocationForInterfaceExtension.ts(3,21): error TS2693: 'string' only refers to a type, but is being used as a value here. | ||
tests/cases/compiler/errorLocationForInterfaceExtension.ts(3,21): error TS18042: An interface cannot extend a primitive type like 'string'. An interface can only extend named object types. | ||
|
||
|
||
==== tests/cases/compiler/errorLocationForInterfaceExtension.ts (1 errors) ==== | ||
var n = ''; | ||
|
||
interface x extends string { } | ||
~~~~~~ | ||
!!! error TS2693: 'string' only refers to a type, but is being used as a value here. | ||
!!! error TS18042: An interface cannot extend a primitive type like 'string'. An interface 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.
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.