Check all properties are present before checking types in relationships
This commit is contained in:
parent
3ea031cf1c
commit
e3b1487240
1 changed files with 17 additions and 18 deletions
|
@ -9424,21 +9424,20 @@ namespace ts {
|
|||
if (relation === identityRelation) {
|
||||
return propertiesIdenticalTo(source, target);
|
||||
}
|
||||
const requireOptionalProperties = relation === subtypeRelation && !(getObjectFlags(source) & ObjectFlags.ObjectLiteral);
|
||||
const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties);
|
||||
if (unmatchedProperty) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Property_0_is_missing_in_type_1, symbolToString(unmatchedProperty), typeToString(source));
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
let result = Ternary.True;
|
||||
const properties = getPropertiesOfObjectType(target);
|
||||
const requireOptionalProperties = relation === subtypeRelation && !(getObjectFlags(source) & ObjectFlags.ObjectLiteral);
|
||||
for (const targetProp of properties) {
|
||||
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
|
||||
if (sourceProp !== targetProp) {
|
||||
if (!sourceProp) {
|
||||
if (!(targetProp.flags & SymbolFlags.Optional) || requireOptionalProperties) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Property_0_is_missing_in_type_1, symbolToString(targetProp), typeToString(source));
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
}
|
||||
else if (!(targetProp.flags & SymbolFlags.Prototype)) {
|
||||
if (!(targetProp.flags & SymbolFlags.Prototype)) {
|
||||
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
|
||||
if (sourceProp && sourceProp !== targetProp) {
|
||||
const sourcePropFlags = getDeclarationModifierFlagsFromSymbol(sourceProp);
|
||||
const targetPropFlags = getDeclarationModifierFlagsFromSymbol(targetProp);
|
||||
if (sourcePropFlags & ModifierFlags.Private || targetPropFlags & ModifierFlags.Private) {
|
||||
|
@ -10463,17 +10462,17 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function isPossiblyAssignableTo(source: Type, target: Type) {
|
||||
function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) {
|
||||
const properties = getPropertiesOfObjectType(target);
|
||||
for (const targetProp of properties) {
|
||||
if (!(targetProp.flags & (SymbolFlags.Optional | SymbolFlags.Prototype))) {
|
||||
const sourceProp = getPropertyOfObjectType(source, targetProp.escapedName);
|
||||
if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional)) {
|
||||
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
|
||||
if (!sourceProp) {
|
||||
return false;
|
||||
return targetProp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) {
|
||||
|
@ -10671,7 +10670,7 @@ namespace ts {
|
|||
}
|
||||
// Infer from the members of source and target only if the two types are possibly related. We check
|
||||
// in both directions because we may be inferring for a co-variant or a contra-variant position.
|
||||
if (isPossiblyAssignableTo(source, target) || isPossiblyAssignableTo(target, source)) {
|
||||
if (!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false) || !getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false)) {
|
||||
inferFromProperties(source, target);
|
||||
inferFromSignatures(source, target, SignatureKind.Call);
|
||||
inferFromSignatures(source, target, SignatureKind.Construct);
|
||||
|
|
Loading…
Reference in a new issue