@@ -9424,21 +9424,20 @@ namespace ts {
9424
9424
if (relation === identityRelation) {
9425
9425
return propertiesIdenticalTo(source, target);
9426
9426
}
9427
+ const requireOptionalProperties = relation === subtypeRelation && !(getObjectFlags(source) & ObjectFlags.ObjectLiteral);
9428
+ const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties);
9429
+ if (unmatchedProperty) {
9430
+ if (reportErrors) {
9431
+ reportError(Diagnostics.Property_0_is_missing_in_type_1, symbolToString(unmatchedProperty), typeToString(source));
9432
+ }
9433
+ return Ternary.False;
9434
+ }
9427
9435
let result = Ternary.True;
9428
9436
const properties = getPropertiesOfObjectType(target);
9429
- const requireOptionalProperties = relation === subtypeRelation && !(getObjectFlags(source) & ObjectFlags.ObjectLiteral);
9430
9437
for (const targetProp of properties) {
9431
- const sourceProp = getPropertyOfType(source, targetProp.escapedName);
9432
- if (sourceProp !== targetProp) {
9433
- if (!sourceProp) {
9434
- if (!(targetProp.flags & SymbolFlags.Optional) || requireOptionalProperties) {
9435
- if (reportErrors) {
9436
- reportError(Diagnostics.Property_0_is_missing_in_type_1, symbolToString(targetProp), typeToString(source));
9437
- }
9438
- return Ternary.False;
9439
- }
9440
- }
9441
- else if (!(targetProp.flags & SymbolFlags.Prototype)) {
9438
+ if (!(targetProp.flags & SymbolFlags.Prototype)) {
9439
+ const sourceProp = getPropertyOfType(source, targetProp.escapedName);
9440
+ if (sourceProp && sourceProp !== targetProp) {
9442
9441
const sourcePropFlags = getDeclarationModifierFlagsFromSymbol(sourceProp);
9443
9442
const targetPropFlags = getDeclarationModifierFlagsFromSymbol(targetProp);
9444
9443
if (sourcePropFlags & ModifierFlags.Private || targetPropFlags & ModifierFlags.Private) {
@@ -10463,17 +10462,17 @@ namespace ts {
10463
10462
}
10464
10463
}
10465
10464
10466
- function isPossiblyAssignableTo (source: Type, target: Type) {
10465
+ function getUnmatchedProperty (source: Type, target: Type, requireOptionalProperties: boolean ) {
10467
10466
const properties = getPropertiesOfObjectType(target);
10468
10467
for (const targetProp of properties) {
10469
- if (!(targetProp.flags & ( SymbolFlags.Optional | SymbolFlags.Prototype) )) {
10470
- const sourceProp = getPropertyOfObjectType (source, targetProp.escapedName);
10468
+ if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional)) {
10469
+ const sourceProp = getPropertyOfType (source, targetProp.escapedName);
10471
10470
if (!sourceProp) {
10472
- return false ;
10471
+ return targetProp ;
10473
10472
}
10474
10473
}
10475
10474
}
10476
- return true ;
10475
+ return undefined ;
10477
10476
}
10478
10477
10479
10478
function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) {
@@ -10671,7 +10670,7 @@ namespace ts {
10671
10670
}
10672
10671
// Infer from the members of source and target only if the two types are possibly related. We check
10673
10672
// in both directions because we may be inferring for a co-variant or a contra-variant position.
10674
- if (isPossiblyAssignableTo (source, target) || isPossiblyAssignableTo (target, source)) {
10673
+ if (!getUnmatchedProperty (source, target, /*requireOptionalProperties*/ false ) || !getUnmatchedProperty (target, source, /*requireOptionalProperties*/ false )) {
10675
10674
inferFromProperties(source, target);
10676
10675
inferFromSignatures(source, target, SignatureKind.Call);
10677
10676
inferFromSignatures(source, target, SignatureKind.Construct);
0 commit comments