Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
This PR fixes #6346 by implementing two changes:
string
(previously it wasany
).An example:
With this PR, the type of
x
is nowstring
and the type ofobj
isMyObject
because the array is indexed with a for-in variable for an array (and thus the for-in variable is known to contain a numeric string). Had the array been indexed with any other string expression, the type of obj would beany
because the string could be the name of a property or method (e.g. "length" or "push").For historical reasons we have used type
any
for for-in variables even though the iterated values are always strings. The reason we used typeany
is that when an array is indexed with an expression of typeany
ornumber
we produce a value of the array element type, and thus the example above produces the correct type forobj
. However, with the second new rule above, indexing with an expression of typestring
can now also produce a value of the array element type if the expression is a for-in variable for an array.The use of type
any
was never a great solution, in particular because theany
is "silent" and not caught by the-noImplicitAny
flag. Furthermore, with the introduction of the new for-of statement in ES2015 it got worse. Consider:This PR is a breaking change for certain (suspicious) constructs. For example:
Previously, the static type of
x
was of typeany
. Thus, even thoughx
contains a string it could be compared to a numeric literal (at run-time this coerces the string operand to a number and then compares that to the numeric operand). This is one of the not so good parts of JavaScript. Mixing of strings and numbers only work for some operators and are a source of many a surprising bug (for example, it doesn't work with the===
operator, and+
concatenates string values instead of adding the numeric values).