Skip to content

Commit 90d20f2

Browse files
committed
Redo subtype reduction with correct --noImplicitAny error reporting
1 parent 709541c commit 90d20f2

File tree

1 file changed

+28
-17
lines changed

1 file changed

+28
-17
lines changed

Diff for: src/compiler/checker.ts

+28-17
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)