@@ -12473,10 +12473,10 @@ namespace ts {
12473
12473
return propertiesIdenticalTo(source, target);
12474
12474
}
12475
12475
const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source) && !isTupleType(source);
12476
- const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties);
12476
+ const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false );
12477
12477
if (unmatchedProperty) {
12478
12478
if (reportErrors) {
12479
- const props = arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties));
12479
+ const props = arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false ));
12480
12480
if (!headMessage || (headMessage.code !== Diagnostics.Class_0_incorrectly_implements_interface_1.code &&
12481
12481
headMessage.code !== Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code)) {
12482
12482
suppressNextError = true; // Retain top-level error for interface implementing issues, otherwise omit it
@@ -13900,20 +13900,29 @@ namespace ts {
13900
13900
return getTypeFromInference(inference);
13901
13901
}
13902
13902
13903
- function* getUnmatchedProperties(source: Type, target: Type, requireOptionalProperties: boolean) {
13903
+ function* getUnmatchedProperties(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean ) {
13904
13904
const properties = target.flags & TypeFlags.Intersection ? getPropertiesOfUnionOrIntersectionType(<IntersectionType>target) : getPropertiesOfObjectType(target);
13905
13905
for (const targetProp of properties) {
13906
13906
if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional)) {
13907
13907
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
13908
13908
if (!sourceProp) {
13909
13909
yield targetProp;
13910
13910
}
13911
+ else if (matchDiscriminantProperties) {
13912
+ const targetType = getTypeOfSymbol(targetProp);
13913
+ if (targetType.flags & TypeFlags.Unit) {
13914
+ const sourceType = getTypeOfSymbol(sourceProp);
13915
+ if (!(sourceType.flags & TypeFlags.Any || getRegularTypeOfLiteralType(sourceType) === getRegularTypeOfLiteralType(targetType))) {
13916
+ yield targetProp;
13917
+ }
13918
+ }
13919
+ }
13911
13920
}
13912
13921
}
13913
13922
}
13914
13923
13915
- function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean): Symbol | undefined {
13916
- return getUnmatchedProperties(source, target, requireOptionalProperties).next().value;
13924
+ function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean ): Symbol | undefined {
13925
+ return getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties ).next().value;
13917
13926
}
13918
13927
13919
13928
function tupleTypesDefinitelyUnrelated(source: TupleTypeReference, target: TupleTypeReference) {
@@ -13925,7 +13934,8 @@ namespace ts {
13925
13934
// Two tuple types with incompatible arities are definitely unrelated.
13926
13935
// Two object types that each have a property that is unmatched in the other are definitely unrelated.
13927
13936
return isTupleType(source) && isTupleType(target) && tupleTypesDefinitelyUnrelated(source, target) ||
13928
- !!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false) && !!getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false);
13937
+ !!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true) &&
13938
+ !!getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true);
13929
13939
}
13930
13940
13931
13941
function getTypeFromInference(inference: InferenceInfo) {
0 commit comments