Skip to content

Commit 7e7057a

Browse files
committed
Empty object type assignable to mapped type with optional properties
1 parent ae92437 commit 7e7057a

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

src/compiler/checker.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7687,7 +7687,7 @@ namespace ts {
76877687
function isKnownProperty(type: Type, name: string): boolean {
76887688
if (type.flags & TypeFlags.Object) {
76897689
const resolved = resolveStructuredTypeMembers(<ObjectType>type);
7690-
if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyObjectType(resolved)) ||
7690+
if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyResolvedType(resolved)) ||
76917691
resolved.stringIndexInfo ||
76927692
(resolved.numberIndexInfo && isNumericLiteralName(name)) ||
76937693
getPropertyOfType(type, name)) {
@@ -7704,14 +7704,18 @@ namespace ts {
77047704
return false;
77057705
}
77067706

7707-
function isEmptyObjectType(t: ResolvedType) {
7707+
function isEmptyResolvedType(t: ResolvedType) {
77087708
return t.properties.length === 0 &&
77097709
t.callSignatures.length === 0 &&
77107710
t.constructSignatures.length === 0 &&
77117711
!t.stringIndexInfo &&
77127712
!t.numberIndexInfo;
77137713
}
77147714

7715+
function isEmptyObjectType(type: Type) {
7716+
return type.flags & TypeFlags.Object && isEmptyResolvedType(resolveStructuredTypeMembers(<ObjectType>type));
7717+
}
7718+
77157719
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
77167720
if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) {
77177721
for (const prop of getPropertiesOfObjectType(source)) {
@@ -7925,10 +7929,14 @@ namespace ts {
79257929
}
79267930
}
79277931
}
7932+
else if ((<MappedType>target).declaration.questionToken && isEmptyObjectType(source)) {
7933+
return Ternary.True;
7934+
7935+
}
79287936
}
79297937
else if (relation !== identityRelation) {
79307938
const resolved = resolveStructuredTypeMembers(<ObjectType>target);
7931-
if (isEmptyObjectType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) {
7939+
if (isEmptyResolvedType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) {
79327940
return Ternary.True;
79337941
}
79347942
}

0 commit comments

Comments
 (0)