Fix excess property check with empty target object type

This commit is contained in:
Anders Hejlsberg
2017-04-06 12:46:59 -07:00
parent dce7fca83d
commit ffab267389

View File

@@ -8328,8 +8328,11 @@ namespace ts {
!t.numberIndexInfo;
}
function isEmptyObjectType(type: Type) {
return type.flags & TypeFlags.Object && isEmptyResolvedType(resolveStructuredTypeMembers(<ObjectType>type));
function isEmptyObjectType(type: Type): boolean {
return type.flags & TypeFlags.Object ? isEmptyResolvedType(resolveStructuredTypeMembers(<ObjectType>type)) :
type.flags & TypeFlags.Union ? forEach((<UnionType>type).types, isEmptyObjectType) :
type.flags & TypeFlags.Intersection ? !forEach((<UnionType>type).types, t => !isEmptyObjectType(t)) :
false;
}
function isEnumTypeRelatedTo(source: EnumType, target: EnumType, errorReporter?: ErrorReporter) {
@@ -8645,14 +8648,8 @@ namespace ts {
function isKnownProperty(type: Type, name: string, isComparingJsxAttributes: boolean): boolean {
if (type.flags & TypeFlags.Object) {
const resolved = resolveStructuredTypeMembers(<ObjectType>type);
if ((relation === assignableRelation || relation === comparableRelation) &&
(type === globalObjectType || (!isComparingJsxAttributes && isEmptyObjectType(resolved)))) {
return true;
}
else if (resolved.stringIndexInfo || (resolved.numberIndexInfo && isNumericLiteralName(name))) {
return true;
}
else if (getPropertyOfType(type, name) || (isComparingJsxAttributes && !isUnhyphenatedJsxName(name))) {
if (resolved.stringIndexInfo || resolved.numberIndexInfo && isNumericLiteralName(name) ||
getPropertyOfType(type, name) || isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) {
// For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known.
return true;
}
@@ -8670,6 +8667,10 @@ namespace ts {
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) {
const isComparingJsxAttributes = !!(source.flags & TypeFlags.JsxAttributes);
if ((relation === assignableRelation || relation === comparableRelation) &&
(target === globalObjectType || (!isComparingJsxAttributes && isEmptyObjectType(target)))) {
return false;
}
for (const prop of getPropertiesOfObjectType(source)) {
if (!isKnownProperty(target, prop.name, isComparingJsxAttributes)) {
if (reportErrors) {