From e086c32bdd949d314344d84ea4e8c577d3c501ea Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 17 Oct 2019 14:13:44 -0700 Subject: [PATCH] A few additional changes --- src/compiler/checker.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 54d2c900f06..02752ed8283 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14604,13 +14604,13 @@ namespace ts { // - For a primitive type or type parameter (such as 'number = A & B') there is no point in // breaking the intersection apart. result = someTypeRelatedToType(source, target, /*reportErrors*/ false, /*isIntersectionConstituent*/ true); - // When the target is a structured type with an index signature, we need to check that every - // constituent of the source intersection relates to the index signature. - if (result && target.flags & TypeFlags.StructuredType && (getIndexInfoOfType(target, IndexKind.String) || getIndexInfoOfType(target, IndexKind.Number))) { - result &= eachTypeRelatedToIndexTypes(source, target, reportErrors); - } } - if (!result && (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable)) { + if (result && source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Object && (getIndexInfoOfType(target, IndexKind.String) || getIndexInfoOfType(target, IndexKind.Number))) { + // When the source is an intersection and the target is an object type with an index signature we check + // that every object type constituent of the source relates to that index signature. + result &= eachTypeRelatedToIndexTypes(source, target, reportErrors); + } + else if (!result && (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable)) { if (result = recursiveTypeRelatedTo(source, target, reportErrors, isIntersectionConstituent)) { resetErrorInfo(saveErrorInfo); } @@ -14933,18 +14933,18 @@ namespace ts { function eachTypeRelatedToIndexTypes(source: IntersectionType, target: Type, reportErrors: boolean): Ternary { let related = Ternary.True; for (const sourceType of source.types) { - const sourceIsPrimitive = !!(sourceType.flags & TypeFlags.Primitive); - if (related) { - related &= indexTypesRelatedTo(sourceType, target, IndexKind.String, sourceIsPrimitive, reportErrors); + if (sourceType.flags & TypeFlags.Object) { if (related) { - related &= indexTypesRelatedTo(sourceType, target, IndexKind.Number, sourceIsPrimitive, reportErrors); + related &= indexTypesRelatedTo(sourceType, target, IndexKind.String, /*sourceIsPrimitive*/ false, reportErrors); + if (related) { + related &= indexTypesRelatedTo(sourceType, target, IndexKind.Number, /*sourceIsPrimitive*/ false, reportErrors); + } } } } return related; } - function typeArgumentsRelatedTo(sources: readonly Type[] = emptyArray, targets: readonly Type[] = emptyArray, variances: readonly VarianceFlags[] = emptyArray, reportErrors: boolean, isIntersectionConstituent: boolean): Ternary { if (sources.length !== targets.length && relation === identityRelation) { return Ternary.False; @@ -15947,7 +15947,7 @@ namespace ts { if (prop.nameType && prop.nameType.flags & TypeFlags.UniqueESSymbol) { continue; } - if (kind === IndexKind.String || isNumericLiteralName(prop.escapedName)) { + if (kind === IndexKind.String || isNumericLiteralName(prop.escapedName) && !isInfinityOrNaNString(prop.escapedName)) { const related = isRelatedTo(getTypeOfSymbol(prop), target, reportErrors); if (!related) { if (reportErrors) {