From 4f32691f3eca56122fb55042ff4bf27daf23ec4b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 20 Jun 2018 23:13:05 -0700 Subject: [PATCH] Try to report errors on types who have matching type references. --- src/compiler/checker.ts | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ff1da5db91..08bd281532 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10851,12 +10851,34 @@ namespace ts { } } if (reportErrors) { - const discriminantType = findMatchingDiscriminantType(source, target); - isRelatedTo(source, discriminantType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true); + const bestMatchingType = + findMatchingDiscriminantType(source, target) || + findMatchingTypeReferenceOrTypeAliasReference(source, target); + + isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true); } return Ternary.False; } + function findMatchingTypeReferenceOrTypeAliasReference(source: Type, unionTarget: UnionOrIntersectionType) { + if (source.flags & TypeFlags.Object && (source as ObjectType).objectFlags & (ObjectFlags.Reference | ObjectFlags.Anonymous) && unionTarget.flags & TypeFlags.Union) { + return find(unionTarget.types, t => { + if (t.flags & TypeFlags.Object) { + if ((source as ObjectType).objectFlags & (t as ObjectType).objectFlags & ObjectFlags.Reference) { + return (source as TypeReference).target === (t as TypeReference).target; + } + if ((source as ObjectType).objectFlags & (t as ObjectType).objectFlags & ObjectFlags.Anonymous) { + // TODO (drosen): Not sure why the following isn't sufficient. + // return !!(source as AnonymousType).aliasSymbol && (source as AnonymousType).aliasSymbol === (target as AnonymousType).aliasSymbol; + return false; + } + } + return false; + }); + } + } + + // Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly function findMatchingDiscriminantType(source: Type, target: UnionOrIntersectionType) { let match: Type | undefined;