diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 780bda03b0a..26c27cb3be2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7687,7 +7687,7 @@ namespace ts { function isKnownProperty(type: Type, name: string): boolean { if (type.flags & TypeFlags.Object) { const resolved = resolveStructuredTypeMembers(type); - if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyObjectType(resolved)) || + if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyResolvedType(resolved)) || resolved.stringIndexInfo || (resolved.numberIndexInfo && isNumericLiteralName(name)) || getPropertyOfType(type, name)) { @@ -7704,7 +7704,7 @@ namespace ts { return false; } - function isEmptyObjectType(t: ResolvedType) { + function isEmptyResolvedType(t: ResolvedType) { return t.properties.length === 0 && t.callSignatures.length === 0 && t.constructSignatures.length === 0 && @@ -7712,6 +7712,10 @@ namespace ts { !t.numberIndexInfo; } + function isEmptyObjectType(type: Type) { + return type.flags & TypeFlags.Object && isEmptyResolvedType(resolveStructuredTypeMembers(type)); + } + function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) { for (const prop of getPropertiesOfObjectType(source)) { @@ -7925,10 +7929,14 @@ namespace ts { } } } + else if ((target).declaration.questionToken && isEmptyObjectType(source)) { + return Ternary.True; + + } } else if (relation !== identityRelation) { const resolved = resolveStructuredTypeMembers(target); - if (isEmptyObjectType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) { + if (isEmptyResolvedType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) { return Ternary.True; } }