@@ -10551,7 +10551,11 @@ namespace ts {
1055110551 }
1055210552 if (type.flags & TypeFlags.Union) {
1055310553 const unionContext = context || createWideningContext(/*parent*/ undefined, /*propertyName*/ undefined, (<UnionType>type).types);
10554- return getUnionType(sameMap((<UnionType>type).types, t => t.flags & TypeFlags.Nullable ? t : getWidenedTypeWithContext(t, unionContext)));
10554+ const widenedTypes = sameMap((<UnionType>type).types, t => t.flags & TypeFlags.Nullable ? t : getWidenedTypeWithContext(t, unionContext));
10555+ // Widening an empty object literal transitions from a highly restrictive type to
10556+ // a highly inclusive one. For that reason we perform subtype reduction here if the
10557+ // union includes empty object types (e.g. reducing {} | string to just {}).
10558+ return getUnionType(widenedTypes, some(widenedTypes, isEmptyObjectType));
1055510559 }
1055610560 if (isArrayType(type) || isTupleType(type)) {
1055710561 return createTypeReference((<TypeReference>type).target, sameMap((<TypeReference>type).typeArguments, getWidenedType));
@@ -10573,28 +10577,35 @@ namespace ts {
1057310577 */
1057410578 function reportWideningErrorsInType(type: Type): boolean {
1057510579 let errorReported = false;
10576- if (type.flags & TypeFlags.Union ) {
10577- for (const t of (<UnionType>type).types ) {
10578- if (reportWideningErrorsInType(t )) {
10580+ if (type.flags & TypeFlags.ContainsWideningType ) {
10581+ if (type.flags & TypeFlags.Union ) {
10582+ if (some((<UnionType>type).types, isEmptyObjectType )) {
1057910583 errorReported = true;
1058010584 }
10585+ else {
10586+ for (const t of (<UnionType>type).types) {
10587+ if (reportWideningErrorsInType(t)) {
10588+ errorReported = true;
10589+ }
10590+ }
10591+ }
1058110592 }
10582- }
10583- if (isArrayType(type) || isTupleType( type)) {
10584- for (const t of (<TypeReference>type).typeArguments ) {
10585- if (reportWideningErrorsInType(t)) {
10586- errorReported = true;
10593+ if (isArrayType(type) || isTupleType(type)) {
10594+ for (const t of (<TypeReference> type).typeArguments ) {
10595+ if (reportWideningErrorsInType(t) ) {
10596+ errorReported = true;
10597+ }
1058710598 }
1058810599 }
10589- }
10590- if (isObjectLiteralType(type)) {
10591- for (const p of getPropertiesOfObjectType(type)) {
10592- const t = getTypeOfSymbol(p);
10593- if (t.flags & TypeFlags.ContainsWideningType) {
10594- if (!reportWideningErrorsInType(t)) {
10595- error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolName(p), typeToString(getWidenedType(t)));
10600+ if (isObjectLiteralType(type)) {
10601+ for (const p of getPropertiesOfObjectType(type)) {
10602+ const t = getTypeOfSymbol(p);
10603+ if (t.flags & TypeFlags.ContainsWideningType) {
10604+ if (!reportWideningErrorsInType(t)) {
10605+ error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolName(p), typeToString(getWidenedType(t)));
10606+ }
10607+ errorReported = true;
1059610608 }
10597- errorReported = true;
1059810609 }
1059910610 }
1060010611 }
0 commit comments