@@ -4897,7 +4897,7 @@ namespace ts {
48974897 if (apparentType.flags & (TypeFlags.ObjectType | TypeFlags.Intersection) && target.flags & TypeFlags.ObjectType) {
48984898 // Report structural errors only if we haven't reported any errors yet
48994899 let reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo;
4900- if (result = objectTypeRelatedTo(apparentType, <ObjectType> target, reportStructuralErrors)) {
4900+ if (result = objectTypeRelatedTo(apparentType, source, target, reportStructuralErrors)) {
49014901 errorInfo = saveErrorInfo;
49024902 return result;
49034903 }
@@ -4919,7 +4919,7 @@ namespace ts {
49194919 return result;
49204920 }
49214921 }
4922- return objectTypeRelatedTo(<ObjectType> source, <ObjectType> target, /*reportErrors*/ false);
4922+ return objectTypeRelatedTo(source, source, target, /*reportErrors*/ false);
49234923 }
49244924 if (source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.TypeParameter) {
49254925 return typeParameterIdenticalTo(<TypeParameter>source, <TypeParameter>target);
@@ -5073,11 +5073,11 @@ namespace ts {
50735073 // Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
50745074 // equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion
50755075 // 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 {
50775077 if (overflow) {
50785078 return Ternary.False;
50795079 }
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;
50815081 let related = relation[id];
50825082 if (related !== undefined) {
50835083 // 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 {
51045104 maybeStack = [];
51055105 expandingFlags = 0;
51065106 }
5107- sourceStack[depth] = source ;
5107+ sourceStack[depth] = apparentSource ;
51085108 targetStack[depth] = target;
51095109 maybeStack[depth] = {};
51105110 maybeStack[depth][id] = RelationComparisonResult.Succeeded;
51115111 depth++;
51125112 let saveExpandingFlags = expandingFlags;
5113- if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source , sourceStack, depth)) expandingFlags |= 1;
5113+ if (!(expandingFlags & 1) && isDeeplyNestedGeneric(apparentSource , sourceStack, depth)) expandingFlags |= 1;
51145114 if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack, depth)) expandingFlags |= 2;
51155115 let result: Ternary;
51165116 if (expandingFlags === 3) {
51175117 result = Ternary.Maybe;
51185118 }
51195119 else {
5120- result = propertiesRelatedTo(source , target, reportErrors);
5120+ result = propertiesRelatedTo(apparentSource , target, reportErrors);
51215121 if (result) {
5122- result &= signaturesRelatedTo(source , target, SignatureKind.Call, reportErrors);
5122+ result &= signaturesRelatedTo(apparentSource , target, SignatureKind.Call, reportErrors);
51235123 if (result) {
5124- result &= signaturesRelatedTo(source , target, SignatureKind.Construct, reportErrors);
5124+ result &= signaturesRelatedTo(apparentSource , target, SignatureKind.Construct, reportErrors);
51255125 if (result) {
5126- result &= stringIndexTypesRelatedTo(source , target, reportErrors);
5126+ result &= stringIndexTypesRelatedTo(apparentSource, originalSource , target, reportErrors);
51275127 if (result) {
5128- result &= numberIndexTypesRelatedTo(source , target, reportErrors);
5128+ result &= numberIndexTypesRelatedTo(apparentSource, originalSource , target, reportErrors);
51295129 }
51305130 }
51315131 }
@@ -5456,12 +5456,17 @@ namespace ts {
54565456 return result;
54575457 }
54585458
5459- function stringIndexTypesRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
5459+ function stringIndexTypesRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: boolean): Ternary {
54605460 if (relation === identityRelation) {
54615461 return indexTypesIdenticalTo(IndexKind.String, source, target);
54625462 }
54635463 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+ }
54655470 let sourceType = getIndexTypeOfType(source, IndexKind.String);
54665471 if (!sourceType) {
54675472 if (reportErrors) {
@@ -5481,12 +5486,17 @@ namespace ts {
54815486 return Ternary.True;
54825487 }
54835488
5484- function numberIndexTypesRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
5489+ function numberIndexTypesRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: boolean): Ternary {
54855490 if (relation === identityRelation) {
54865491 return indexTypesIdenticalTo(IndexKind.Number, source, target);
54875492 }
54885493 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+ }
54905500 let sourceStringType = getIndexTypeOfType(source, IndexKind.String);
54915501 let sourceNumberType = getIndexTypeOfType(source, IndexKind.Number);
54925502 if (!(sourceStringType || sourceNumberType)) {
0 commit comments