diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index db02365fd17..2bd5d40bffa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11185,13 +11185,10 @@ namespace ts { } } - if (relation !== comparableRelation && - !(source.flags & TypeFlags.Union) && - !(target.flags & TypeFlags.Union) && - !isIntersectionConstituent && - source !== globalObjectType && + if (relation !== comparableRelation && !isIntersectionConstituent && + source.flags & (TypeFlags.Primitive | TypeFlags.Object | TypeFlags.Intersection) && source !== globalObjectType && + target.flags & (TypeFlags.Object | TypeFlags.Intersection) && isWeakType(target) && (getPropertiesOfType(source).length > 0 || typeHasCallOrConstructSignatures(source)) && - isWeakType(target) && !hasCommonProperties(source, target)) { if (reportErrors) { const calls = getSignaturesOfType(source, SignatureKind.Call); @@ -12011,34 +12008,6 @@ namespace ts { return result; } - /** - * A type is 'weak' if it is an object type with at least one optional property - * and no required properties, call/construct signatures or index signatures - */ - function isWeakType(type: Type): boolean { - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type); - return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 && - !resolved.stringIndexInfo && !resolved.numberIndexInfo && - resolved.properties.length > 0 && - every(resolved.properties, p => !!(p.flags & SymbolFlags.Optional)); - } - if (type.flags & TypeFlags.Intersection) { - return every((type).types, isWeakType); - } - return false; - } - - function hasCommonProperties(source: Type, target: Type) { - const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); - for (const prop of getPropertiesOfType(source)) { - if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { - return true; - } - } - return false; - } - function propertiesIdenticalTo(source: Type, target: Type): Ternary { if (!(source.flags & TypeFlags.Object && target.flags & TypeFlags.Object)) { return Ternary.False; @@ -12283,6 +12252,34 @@ namespace ts { } } + /** + * A type is 'weak' if it is an object type with at least one optional property + * and no required properties, call/construct signatures or index signatures + */ + function isWeakType(type: Type): boolean { + if (type.flags & TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(type); + return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 && + !resolved.stringIndexInfo && !resolved.numberIndexInfo && + resolved.properties.length > 0 && + every(resolved.properties, p => !!(p.flags & SymbolFlags.Optional)); + } + if (type.flags & TypeFlags.Intersection) { + return every((type).types, isWeakType); + } + return false; + } + + function hasCommonProperties(source: Type, target: Type) { + const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); + for (const prop of getPropertiesOfType(source)) { + if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { + return true; + } + } + return false; + } + // Return a type reference where the source type parameter is replaced with the target marker // type, and flag the result as a marker type reference. function getMarkerTypeReference(type: GenericType, source: TypeParameter, target: Type) {