-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Change for-in iteration variable type from any to string
- Loading branch information
1 parent
ba0f7f5
commit a05b1de
Showing
1 changed file
with
24 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2520,9 +2520,9 @@ namespace ts { | |
|
||
// Return the inferred type for a variable, parameter, or property declaration | ||
function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration): Type { | ||
// A variable declared in a for..in statement is always of type any | ||
// A variable declared in a for..in statement is always of type string | ||
if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) { | ||
return anyType; | ||
return stringType; | ||
} | ||
|
||
if (declaration.parent.parent.kind === SyntaxKind.ForOfStatement) { | ||
|
@@ -8563,6 +8563,23 @@ namespace ts { | |
return true; | ||
} | ||
|
||
/** | ||
* Return true if given node is an expression consisting of an identifier (possibly parenthesized) | ||
* that references a variable declared in a for-in statement for an array-like object. | ||
*/ | ||
function isForInVariableForArrayLikeObject(node: Expression) { | ||
const e = skipParenthesizedNodes(node); | ||
if (e.kind === SyntaxKind.Identifier) { | ||
const symbol = getResolvedSymbol(<Identifier>e); | ||
if (symbol.flags & SymbolFlags.Variable) { | ||
const parent = symbol.valueDeclaration.parent.parent; | ||
return parent.kind === SyntaxKind.ForInStatement && | ||
isArrayLikeType(checkExpression((<ForInStatement>parent).expression)); | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
function checkIndexedAccess(node: ElementAccessExpression): Type { | ||
// Grammar checking | ||
if (!node.argumentExpression) { | ||
|
@@ -8623,7 +8640,7 @@ namespace ts { | |
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) { | ||
|
||
// Try to use a number indexer. | ||
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike)) { | ||
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike) || isForInVariableForArrayLikeObject(node.argumentExpression)) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
ahejlsberg
Author
Member
|
||
const numberIndexType = getIndexTypeOfType(objectType, IndexKind.Number); | ||
if (numberIndexType) { | ||
return numberIndexType; | ||
|
@@ -12697,7 +12714,8 @@ namespace ts { | |
} | ||
// For a binding pattern, validate the initializer and exit | ||
if (isBindingPattern(node.name)) { | ||
if (node.initializer) { | ||
// Don't validate for-in initializer as it is already an error | ||
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) { | ||
checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined); | ||
checkParameterInitializer(node); | ||
} | ||
|
@@ -12707,7 +12725,8 @@ namespace ts { | |
const type = getTypeOfVariableOrParameterOrProperty(symbol); | ||
if (node === symbol.valueDeclaration) { | ||
// Node is the primary declaration of the symbol, just validate the initializer | ||
if (node.initializer) { | ||
// Don't validate for-in initializer as it is already an error | ||
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) { | ||
checkTypeAssignableTo(checkExpressionCached(node.initializer), type, node, /*headMessage*/ undefined); | ||
checkParameterInitializer(node); | ||
} | ||
|
1 comment
on commit a05b1de
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
isForInVariableForArrayLikeObject
ever be true whenindexType
is anESSymbol
? If so, can you give an example in the new tests because I don't know what it would look like. If not, maybe update the comment.