From ae386a9c32c75564e73fd3c3e221126ba2c84341 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 5 Apr 2017 11:07:23 -0700 Subject: [PATCH] Remove {} from intersection types that already contain object types --- src/compiler/checker.ts | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d9852e78c3f..0d07d6a7498 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6906,6 +6906,8 @@ namespace ts { containsString?: boolean; containsNumber?: boolean; containsStringOrNumberLiteral?: boolean; + containsObjectType?: boolean; + containsEmptyObject?: boolean; unionIndex?: number; } @@ -7101,7 +7103,13 @@ namespace ts { else if (type.flags & TypeFlags.Any) { typeSet.containsAny = true; } + else if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) { + typeSet.containsEmptyObject = true; + } else if (!(type.flags & TypeFlags.Never) && (strictNullChecks || !(type.flags & TypeFlags.Nullable)) && !contains(typeSet, type)) { + if (type.flags & TypeFlags.Object) { + typeSet.containsObjectType = true; + } if (type.flags & TypeFlags.Union && typeSet.unionIndex === undefined) { typeSet.unionIndex = typeSet.length; } @@ -7139,6 +7147,9 @@ namespace ts { if (typeSet.containsAny) { return anyType; } + if (typeSet.containsEmptyObject && !typeSet.containsObjectType) { + typeSet.push(emptyObjectType); + } if (typeSet.length === 1) { return typeSet[0]; } @@ -8309,6 +8320,18 @@ namespace ts { } } + function isEmptyResolvedType(t: ResolvedType) { + return t.properties.length === 0 && + t.callSignatures.length === 0 && + t.constructSignatures.length === 0 && + !t.stringIndexInfo && + !t.numberIndexInfo; + } + + function isEmptyObjectType(type: Type) { + return type.flags & TypeFlags.Object && isEmptyResolvedType(resolveStructuredTypeMembers(type)); + } + function isEnumTypeRelatedTo(source: EnumType, target: EnumType, errorReporter?: ErrorReporter) { if (source === target) { return true; @@ -8644,18 +8667,6 @@ namespace ts { return false; } - function isEmptyResolvedType(t: ResolvedType) { - return t.properties.length === 0 && - t.callSignatures.length === 0 && - t.constructSignatures.length === 0 && - !t.stringIndexInfo && - !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)) { const isComparingJsxAttributes = !!(source.flags & TypeFlags.JsxAttributes);