@@ -6037,19 +6037,20 @@ namespace ts {
6037
6037
const id = objectType.id + "," + indexType.id;
6038
6038
return indexedAccessTypes[id] || (indexedAccessTypes[id] = createIndexedAccessType(objectType, indexType));
6039
6039
}
6040
- const apparentType = getApparentType(objectType);
6041
- if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Primitive)) {
6040
+ const apparentObjectType = getApparentType(objectType);
6041
+ const apparentIndexType = indexType.flags & TypeFlags.Index ? stringOrNumberType : indexType;
6042
+ if (apparentIndexType.flags & TypeFlags.Union && !(apparentIndexType.flags & TypeFlags.Primitive)) {
6042
6043
const propTypes: Type[] = [];
6043
- for (const t of (<UnionType>indexType ).types) {
6044
- const propType = getPropertyTypeForIndexType(apparentType , t, accessNode, /*cacheSymbol*/ false);
6044
+ for (const t of (<UnionType>apparentIndexType ).types) {
6045
+ const propType = getPropertyTypeForIndexType(apparentObjectType , t, accessNode, /*cacheSymbol*/ false);
6045
6046
if (propType === unknownType) {
6046
6047
return unknownType;
6047
6048
}
6048
6049
propTypes.push(propType);
6049
6050
}
6050
6051
return getUnionType(propTypes);
6051
6052
}
6052
- return getPropertyTypeForIndexType(apparentType, indexType , accessNode, /*cacheSymbol*/ true);
6053
+ return getPropertyTypeForIndexType(apparentObjectType, apparentIndexType , accessNode, /*cacheSymbol*/ true);
6053
6054
}
6054
6055
6055
6056
function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) {
@@ -7123,7 +7124,10 @@ namespace ts {
7123
7124
7124
7125
if (source.flags & TypeFlags.Index) {
7125
7126
// A keyof T is related to a union type containing both string and number
7126
- if (maybeTypeOfKind(target, TypeFlags.String) && maybeTypeOfKind(target, TypeFlags.Number)) {
7127
+ const related = relation === comparableRelation ?
7128
+ maybeTypeOfKind(target, TypeFlags.String | TypeFlags.Number) :
7129
+ maybeTypeOfKind(target, TypeFlags.String) && maybeTypeOfKind(target, TypeFlags.Number);
7130
+ if (related) {
7127
7131
return Ternary.True;
7128
7132
}
7129
7133
}
@@ -14254,7 +14258,7 @@ namespace ts {
14254
14258
if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
14255
14259
error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
14256
14260
}
14257
- if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter)) {
14261
+ if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess )) {
14258
14262
error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
14259
14263
}
14260
14264
return booleanType;
@@ -17148,7 +17152,7 @@ namespace ts {
17148
17152
const rightType = checkNonNullExpression(node.expression);
17149
17153
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
17150
17154
// in this case error about missing name is already reported - do not report extra one
17151
- if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter)) {
17155
+ if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess )) {
17152
17156
error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
17153
17157
}
17154
17158
0 commit comments