@@ -3205,7 +3205,7 @@ namespace ts {
3205
3205
// right hand expression is of a type parameter type.
3206
3206
if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) {
3207
3207
const indexType = getIndexType(checkNonNullExpression((<ForInStatement>declaration.parent.parent).expression));
3208
- return indexType.flags & TypeFlags.Index ? indexType : stringType;
3208
+ return indexType.flags & ( TypeFlags.TypeParameter | TypeFlags. Index) ? indexType : stringType;
3209
3209
}
3210
3210
3211
3211
if (declaration.parent.parent.kind === SyntaxKind.ForOfStatement) {
@@ -5920,6 +5920,11 @@ namespace ts {
5920
5920
getLiteralTypeFromPropertyNames(type);
5921
5921
}
5922
5922
5923
+ function getIndexTypeOrString(type: Type): Type {
5924
+ const indexType = getIndexType(type);
5925
+ return indexType !== neverType ? indexType : stringType;
5926
+ }
5927
+
5923
5928
function getTypeFromTypeOperatorNode(node: TypeOperatorNode) {
5924
5929
const links = getNodeLinks(node);
5925
5930
if (!links.resolvedType) {
@@ -6018,8 +6023,7 @@ namespace ts {
6018
6023
// meaningfully access the properties of the object type. In those cases, we first check that the
6019
6024
// index type is assignable to 'keyof T' for the object type.
6020
6025
if (accessNode) {
6021
- const keyType = indexType.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>indexType) || emptyObjectType : indexType;
6022
- if (!isTypeAssignableTo(keyType, getIndexType(objectType))) {
6026
+ if (!isTypeAssignableTo(indexType, getIndexType(objectType))) {
6023
6027
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
6024
6028
return unknownType;
6025
6029
}
@@ -14275,7 +14279,7 @@ namespace ts {
14275
14279
// The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
14276
14280
// and the right operand to be of type Any, an object type, or a type parameter type.
14277
14281
// The result is always of the Boolean primitive type.
14278
- if (!isTypeAnyOrAllConstituentTypesHaveKind( leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
14282
+ if (!(isTypeComparableTo( leftType, stringType) || isTypeOfKind(leftType, TypeFlags.NumberLike | TypeFlags.ESSymbol) )) {
14279
14283
error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
14280
14284
}
14281
14285
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
@@ -17166,6 +17170,7 @@ namespace ts {
17166
17170
// Grammar checking
17167
17171
checkGrammarForInOrForOfStatement(node);
17168
17172
17173
+ const rightType = checkNonNullExpression(node.expression);
17169
17174
// TypeScript 1.0 spec (April 2014): 5.4
17170
17175
// In a 'for-in' statement of the form
17171
17176
// for (let VarDecl in Expr) Statement
@@ -17176,7 +17181,6 @@ namespace ts {
17176
17181
if (variable && isBindingPattern(variable.name)) {
17177
17182
error(variable.name, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
17178
17183
}
17179
-
17180
17184
checkForInOrForOfVariableDeclaration(node);
17181
17185
}
17182
17186
else {
@@ -17189,7 +17193,7 @@ namespace ts {
17189
17193
if (varExpr.kind === SyntaxKind.ArrayLiteralExpression || varExpr.kind === SyntaxKind.ObjectLiteralExpression) {
17190
17194
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
17191
17195
}
17192
- else if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike )) {
17196
+ else if (!isTypeAssignableTo(getIndexTypeOrString(rightType), leftType )) {
17193
17197
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
17194
17198
}
17195
17199
else {
@@ -17198,7 +17202,6 @@ namespace ts {
17198
17202
}
17199
17203
}
17200
17204
17201
- const rightType = checkNonNullExpression(node.expression);
17202
17205
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
17203
17206
// in this case error about missing name is already reported - do not report extra one
17204
17207
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
0 commit comments