@@ -10551,7 +10551,11 @@ namespace ts {
10551
10551
}
10552
10552
if (type.flags & TypeFlags.Union) {
10553
10553
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));
10555
10559
}
10556
10560
if (isArrayType(type) || isTupleType(type)) {
10557
10561
return createTypeReference((<TypeReference>type).target, sameMap((<TypeReference>type).typeArguments, getWidenedType));
@@ -10573,28 +10577,35 @@ namespace ts {
10573
10577
*/
10574
10578
function reportWideningErrorsInType(type: Type): boolean {
10575
10579
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 )) {
10579
10583
errorReported = true;
10580
10584
}
10585
+ else {
10586
+ for (const t of (<UnionType>type).types) {
10587
+ if (reportWideningErrorsInType(t)) {
10588
+ errorReported = true;
10589
+ }
10590
+ }
10591
+ }
10581
10592
}
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
+ }
10587
10598
}
10588
10599
}
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;
10596
10608
}
10597
- errorReported = true;
10598
10609
}
10599
10610
}
10600
10611
}
0 commit comments