-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Check destructuring validity the same way element accesses and indexed accesses are checked #24700
Check destructuring validity the same way element accesses and indexed accesses are checked #24700
Conversation
…d accesses are checked
// 1: | ||
for (let {[a]: a} of [{ }]) continue; | ||
~ | ||
!!! error TS2448: Block-scoped variable 'a' used before its declaration. | ||
~ | ||
!!! error TS2538: Type 'any' cannot be used as an index type. |
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.
This doesn't feel like a legal error, but it seems like we're only issuing it when there's already an error on the same node. Is there an issue with the error type leaking out into an error message?
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.
Most certainly. It's because we choose to consider indexing with any
an error today (esp. if the thing being indexed has no index signatures), but destructuring accesses don't flag that right now. This PR aligns them.
? getLateBoundNameFromType(indexType) | ||
: accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) | ||
? getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>accessExpression.argumentExpression).name)) | ||
: accessNode && isPropertyName(accessNode) |
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 need this case.
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.
Needed to handle well-known symbol names, which are not normal property names or unique symbols:
let { [Symbol.iterator]: destructured } = []
@@ -9521,7 +9499,7 @@ namespace ts { | |||
return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); | |||
} | |||
|
|||
function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode, missingType = accessNode ? errorType : unknownType): Type { | |||
function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName, useApparentObjectType?: boolean, missingType = accessNode ? errorType : unknownType): Type { |
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.
No extra flag please.
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.
It's now gone, and I'm using the raw apparent type as the input directly instead. The downside is that error messages now reference the apparent type instead of the original type, too.
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.
Just one minor change, otherwise looks good.
return errorType; | ||
} | ||
const exprType = isComputedPropertyName(name) | ||
? checkExpression(name.expression) |
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.
Use checkComputedPropertyName
here.
Fixes #24661
This causes some error messages to change to match the indexing case (IMO, good for consistency, since the messages were almost the same). To preserve some semantics destructuring had with private/protected members of generics (eg,
this
), some shuffling of apparent types had to be done as well. Lastly, we seem to actually pick up a few error cases we somehow just missed before, eg, destructuring with astring
computed name when there's nostring
index signature.