@@ -4897,7 +4897,7 @@ namespace ts {
4897
4897
if (apparentType.flags & (TypeFlags.ObjectType | TypeFlags.Intersection) && target.flags & TypeFlags.ObjectType) {
4898
4898
// Report structural errors only if we haven't reported any errors yet
4899
4899
let reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo;
4900
- if (result = objectTypeRelatedTo(apparentType, <ObjectType> target, reportStructuralErrors)) {
4900
+ if (result = objectTypeRelatedTo(apparentType, source, target, reportStructuralErrors)) {
4901
4901
errorInfo = saveErrorInfo;
4902
4902
return result;
4903
4903
}
@@ -4919,7 +4919,7 @@ namespace ts {
4919
4919
return result;
4920
4920
}
4921
4921
}
4922
- return objectTypeRelatedTo(<ObjectType> source, <ObjectType> target, /*reportErrors*/ false);
4922
+ return objectTypeRelatedTo(source, source, target, /*reportErrors*/ false);
4923
4923
}
4924
4924
if (source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.TypeParameter) {
4925
4925
return typeParameterIdenticalTo(<TypeParameter>source, <TypeParameter>target);
@@ -5073,11 +5073,11 @@ namespace ts {
5073
5073
// Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
5074
5074
// equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion
5075
5075
// and issue an error. Otherwise, actually compare the structure of the two types.
5076
- function objectTypeRelatedTo(source : Type, target: Type, reportErrors: boolean): Ternary {
5076
+ function objectTypeRelatedTo(apparentSource: Type, originalSource : Type, target: Type, reportErrors: boolean): Ternary {
5077
5077
if (overflow) {
5078
5078
return Ternary.False;
5079
5079
}
5080
- let id = relation !== identityRelation || source .id < target.id ? source .id + "," + target.id : target.id + "," + source .id;
5080
+ let id = relation !== identityRelation || apparentSource .id < target.id ? apparentSource .id + "," + target.id : target.id + "," + apparentSource .id;
5081
5081
let related = relation[id];
5082
5082
if (related !== undefined) {
5083
5083
// If we computed this relation already and it was failed and reported, or if we're not being asked to elaborate
@@ -5104,28 +5104,28 @@ namespace ts {
5104
5104
maybeStack = [];
5105
5105
expandingFlags = 0;
5106
5106
}
5107
- sourceStack[depth] = source ;
5107
+ sourceStack[depth] = apparentSource ;
5108
5108
targetStack[depth] = target;
5109
5109
maybeStack[depth] = {};
5110
5110
maybeStack[depth][id] = RelationComparisonResult.Succeeded;
5111
5111
depth++;
5112
5112
let saveExpandingFlags = expandingFlags;
5113
- if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source , sourceStack, depth)) expandingFlags |= 1;
5113
+ if (!(expandingFlags & 1) && isDeeplyNestedGeneric(apparentSource , sourceStack, depth)) expandingFlags |= 1;
5114
5114
if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack, depth)) expandingFlags |= 2;
5115
5115
let result: Ternary;
5116
5116
if (expandingFlags === 3) {
5117
5117
result = Ternary.Maybe;
5118
5118
}
5119
5119
else {
5120
- result = propertiesRelatedTo(source , target, reportErrors);
5120
+ result = propertiesRelatedTo(apparentSource , target, reportErrors);
5121
5121
if (result) {
5122
- result &= signaturesRelatedTo(source , target, SignatureKind.Call, reportErrors);
5122
+ result &= signaturesRelatedTo(apparentSource , target, SignatureKind.Call, reportErrors);
5123
5123
if (result) {
5124
- result &= signaturesRelatedTo(source , target, SignatureKind.Construct, reportErrors);
5124
+ result &= signaturesRelatedTo(apparentSource , target, SignatureKind.Construct, reportErrors);
5125
5125
if (result) {
5126
- result &= stringIndexTypesRelatedTo(source , target, reportErrors);
5126
+ result &= stringIndexTypesRelatedTo(apparentSource, originalSource , target, reportErrors);
5127
5127
if (result) {
5128
- result &= numberIndexTypesRelatedTo(source , target, reportErrors);
5128
+ result &= numberIndexTypesRelatedTo(apparentSource, originalSource , target, reportErrors);
5129
5129
}
5130
5130
}
5131
5131
}
@@ -5456,12 +5456,17 @@ namespace ts {
5456
5456
return result;
5457
5457
}
5458
5458
5459
- function stringIndexTypesRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
5459
+ function stringIndexTypesRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: boolean): Ternary {
5460
5460
if (relation === identityRelation) {
5461
5461
return indexTypesIdenticalTo(IndexKind.String, source, target);
5462
5462
}
5463
5463
let targetType = getIndexTypeOfType(target, IndexKind.String);
5464
- if (targetType && !(targetType.flags & TypeFlags.Any)) {
5464
+ if (targetType) {
5465
+ if ((targetType.flags & TypeFlags.Any) && !(originalSource.flags & TypeFlags.Primitive)) {
5466
+ // non-primitive assignment to any is always allowed, eg
5467
+ // `var x: { [index: string]: any } = { property: 12 };`
5468
+ return Ternary.True;
5469
+ }
5465
5470
let sourceType = getIndexTypeOfType(source, IndexKind.String);
5466
5471
if (!sourceType) {
5467
5472
if (reportErrors) {
@@ -5481,12 +5486,17 @@ namespace ts {
5481
5486
return Ternary.True;
5482
5487
}
5483
5488
5484
- function numberIndexTypesRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
5489
+ function numberIndexTypesRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: boolean): Ternary {
5485
5490
if (relation === identityRelation) {
5486
5491
return indexTypesIdenticalTo(IndexKind.Number, source, target);
5487
5492
}
5488
5493
let targetType = getIndexTypeOfType(target, IndexKind.Number);
5489
- if (targetType && !(targetType.flags & TypeFlags.Any)) {
5494
+ if (targetType) {
5495
+ if ((targetType.flags & TypeFlags.Any) && !(originalSource.flags & TypeFlags.Primitive)) {
5496
+ // non-primitive assignment to any is always allowed, eg
5497
+ // `var x: { [index: number]: any } = { property: 12 };`
5498
+ return Ternary.True;
5499
+ }
5490
5500
let sourceStringType = getIndexTypeOfType(source, IndexKind.String);
5491
5501
let sourceNumberType = getIndexTypeOfType(source, IndexKind.Number);
5492
5502
if (!(sourceStringType || sourceNumberType)) {
0 commit comments