Skip to content

Commit

Permalink
Skip parent error when reporting excess property checks (#55152)
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanCavanaugh committed Aug 7, 2023
1 parent 5ea2952 commit 9a771d5
Show file tree
Hide file tree
Showing 117 changed files with 855 additions and 1,236 deletions.
19 changes: 16 additions & 3 deletions src/compiler/checker.ts
Expand Up @@ -20369,6 +20369,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
let expandingFlags = ExpandingFlags.None;
let overflow = false;
let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid
let skipParentCounter = 0; // How many errors should be skipped 'above' in the elaboration pyramid
let lastSkippedInfo: [Type, Type] | undefined;
let incompatibleStack: DiagnosticAndArguments[] | undefined;

Expand Down Expand Up @@ -20430,6 +20431,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
lastSkippedInfo = saved.lastSkippedInfo;
incompatibleStack = saved.incompatibleStack;
overrideNextErrorInfo = saved.overrideNextErrorInfo;
skipParentCounter = saved.skipParentCounter;
relatedInfo = saved.relatedInfo;
}

Expand All @@ -20439,6 +20441,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
lastSkippedInfo,
incompatibleStack: incompatibleStack?.slice(),
overrideNextErrorInfo,
skipParentCounter,
relatedInfo: relatedInfo?.slice() as [DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]] | undefined,
};
}
Expand Down Expand Up @@ -20561,7 +20564,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
Debug.assert(!!errorNode);
if (incompatibleStack) reportIncompatibleStack();
if (message.elidedInCompatabilityPyramid) return;
errorInfo = chainDiagnosticMessages(errorInfo, message, ...args);
if (skipParentCounter === 0) {
errorInfo = chainDiagnosticMessages(errorInfo, message, ...args);
}
else {
skipParentCounter--;
}
}

function reportParentSkippedError(message: DiagnosticMessage, ...args: DiagnosticArguments): void {
reportError(message, ...args);
skipParentCounter++;
}

function associateRelatedInfo(info: DiagnosticRelatedInformation) {
Expand Down Expand Up @@ -20958,11 +20971,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
if (suggestion !== undefined) {
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2,
reportParentSkippedError(Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2,
symbolToString(prop), typeToString(errorTarget), suggestion);
}
else {
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
reportParentSkippedError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
symbolToString(prop), typeToString(errorTarget));
}
}
Expand Down
6 changes: 2 additions & 4 deletions tests/baselines/reference/arrayCast.errors.txt
@@ -1,6 +1,5 @@
arrayCast.ts(3,23): error TS2352: Conversion of type '{ foo: string; }[]' to type '{ id: number; }[]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Type '{ foo: string; }' is not comparable to type '{ id: number; }'.
Object literal may only specify known properties, and 'foo' does not exist in type '{ id: number; }'.
Object literal may only specify known properties, and 'foo' does not exist in type '{ id: number; }'.


==== arrayCast.ts (1 errors) ====
Expand All @@ -9,8 +8,7 @@ arrayCast.ts(3,23): error TS2352: Conversion of type '{ foo: string; }[]' to typ
<{ id: number; }[]>[{ foo: "s" }];
~~~
!!! error TS2352: Conversion of type '{ foo: string; }[]' to type '{ id: number; }[]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
!!! error TS2352: Type '{ foo: string; }' is not comparable to type '{ id: number; }'.
!!! error TS2352: Object literal may only specify known properties, and 'foo' does not exist in type '{ id: number; }'.
!!! error TS2352: Object literal may only specify known properties, and 'foo' does not exist in type '{ id: number; }'.

// Should succeed, as the {} element causes the type of the array to be {}[]
<{ id: number; }[]>[{ foo: "s" }, {}];
24 changes: 8 additions & 16 deletions tests/baselines/reference/arrayLiteralTypeInference.errors.txt
@@ -1,11 +1,7 @@
arrayLiteralTypeInference.ts(14,14): error TS2322: Type '{ id: number; trueness: false; }' is not assignable to type 'Action'.
Object literal may only specify known properties, and 'trueness' does not exist in type 'Action'.
arrayLiteralTypeInference.ts(15,14): error TS2322: Type '{ id: number; name: string; }' is not assignable to type 'Action'.
Object literal may only specify known properties, and 'name' does not exist in type 'Action'.
arrayLiteralTypeInference.ts(31,18): error TS2322: Type '{ id: number; trueness: false; }' is not assignable to type '{ id: number; }'.
Object literal may only specify known properties, and 'trueness' does not exist in type '{ id: number; }'.
arrayLiteralTypeInference.ts(32,18): error TS2322: Type '{ id: number; name: string; }' is not assignable to type '{ id: number; }'.
Object literal may only specify known properties, and 'name' does not exist in type '{ id: number; }'.
arrayLiteralTypeInference.ts(14,14): error TS2353: Object literal may only specify known properties, and 'trueness' does not exist in type 'Action'.
arrayLiteralTypeInference.ts(15,14): error TS2353: Object literal may only specify known properties, and 'name' does not exist in type 'Action'.
arrayLiteralTypeInference.ts(31,18): error TS2353: Object literal may only specify known properties, and 'trueness' does not exist in type '{ id: number; }'.
arrayLiteralTypeInference.ts(32,18): error TS2353: Object literal may only specify known properties, and 'name' does not exist in type '{ id: number; }'.


==== arrayLiteralTypeInference.ts (4 errors) ====
Expand All @@ -24,12 +20,10 @@ arrayLiteralTypeInference.ts(32,18): error TS2322: Type '{ id: number; name: str
var x1: Action[] = [
{ id: 2, trueness: false },
~~~~~~~~
!!! error TS2322: Type '{ id: number; trueness: false; }' is not assignable to type 'Action'.
!!! error TS2322: Object literal may only specify known properties, and 'trueness' does not exist in type 'Action'.
!!! error TS2353: Object literal may only specify known properties, and 'trueness' does not exist in type 'Action'.
{ id: 3, name: "three" }
~~~~
!!! error TS2322: Type '{ id: number; name: string; }' is not assignable to type 'Action'.
!!! error TS2322: Object literal may only specify known properties, and 'name' does not exist in type 'Action'.
!!! error TS2353: Object literal may only specify known properties, and 'name' does not exist in type 'Action'.
]

var x2: Action[] = [
Expand All @@ -47,12 +41,10 @@ arrayLiteralTypeInference.ts(32,18): error TS2322: Type '{ id: number; name: str
[
{ id: 2, trueness: false },
~~~~~~~~
!!! error TS2322: Type '{ id: number; trueness: false; }' is not assignable to type '{ id: number; }'.
!!! error TS2322: Object literal may only specify known properties, and 'trueness' does not exist in type '{ id: number; }'.
!!! error TS2353: Object literal may only specify known properties, and 'trueness' does not exist in type '{ id: number; }'.
{ id: 3, name: "three" }
~~~~
!!! error TS2322: Type '{ id: number; name: string; }' is not assignable to type '{ id: number; }'.
!!! error TS2322: Object literal may only specify known properties, and 'name' does not exist in type '{ id: number; }'.
!!! error TS2353: Object literal may only specify known properties, and 'name' does not exist in type '{ id: number; }'.
]

var z2: { id: number }[] =
Expand Down
12 changes: 4 additions & 8 deletions tests/baselines/reference/arrayLiterals.errors.txt
@@ -1,7 +1,5 @@
arrayLiterals.ts(24,77): error TS2322: Type '{ a: string; b: number; c: string; }' is not assignable to type '{ a: string; b: number; }'.
Object literal may only specify known properties, and 'c' does not exist in type '{ a: string; b: number; }'.
arrayLiterals.ts(24,101): error TS2322: Type '{ a: string; b: number; c: number; }' is not assignable to type '{ a: string; b: number; }'.
Object literal may only specify known properties, and 'c' does not exist in type '{ a: string; b: number; }'.
arrayLiterals.ts(24,77): error TS2353: Object literal may only specify known properties, and 'c' does not exist in type '{ a: string; b: number; }'.
arrayLiterals.ts(24,101): error TS2353: Object literal may only specify known properties, and 'c' does not exist in type '{ a: string; b: number; }'.


==== arrayLiterals.ts (2 errors) ====
Expand Down Expand Up @@ -30,12 +28,10 @@ arrayLiterals.ts(24,101): error TS2322: Type '{ a: string; b: number; c: number;
// Contextual type C with numeric index signature makes array literal of EveryType E of type BCT(E,C)[]
var context1: { [n: number]: { a: string; b: number; }; } = [{ a: '', b: 0, c: '' }, { a: "", b: 3, c: 0 }];
~
!!! error TS2322: Type '{ a: string; b: number; c: string; }' is not assignable to type '{ a: string; b: number; }'.
!!! error TS2322: Object literal may only specify known properties, and 'c' does not exist in type '{ a: string; b: number; }'.
!!! error TS2353: Object literal may only specify known properties, and 'c' does not exist in type '{ a: string; b: number; }'.
!!! related TS6501 arrayLiterals.ts:24:17: The expected type comes from this index signature.
~
!!! error TS2322: Type '{ a: string; b: number; c: number; }' is not assignable to type '{ a: string; b: number; }'.
!!! error TS2322: Object literal may only specify known properties, and 'c' does not exist in type '{ a: string; b: number; }'.
!!! error TS2353: Object literal may only specify known properties, and 'c' does not exist in type '{ a: string; b: number; }'.
!!! related TS6501 arrayLiterals.ts:24:17: The expected type comes from this index signature.
var context2 = [{ a: '', b: 0, c: '' }, { a: "", b: 3, c: 0 }];

Expand Down
18 changes: 6 additions & 12 deletions tests/baselines/reference/assignmentCompatBug2.errors.txt
@@ -1,9 +1,6 @@
assignmentCompatBug2.ts(1,27): error TS2322: Type '{ a: number; }' is not assignable to type '{ b: number; }'.
Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.
assignmentCompatBug2.ts(3,8): error TS2322: Type '{ a: number; }' is not assignable to type '{ b: number; }'.
Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.
assignmentCompatBug2.ts(5,13): error TS2322: Type '{ b: number; a: number; }' is not assignable to type '{ b: number; }'.
Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.
assignmentCompatBug2.ts(1,27): error TS2353: Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.
assignmentCompatBug2.ts(3,8): error TS2353: Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.
assignmentCompatBug2.ts(5,13): error TS2353: Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.
assignmentCompatBug2.ts(15,1): error TS2741: Property 'm' is missing in type '{ f: (n: number) => number; g: (s: string) => number; }' but required in type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'.
assignmentCompatBug2.ts(20,1): error TS2741: Property 'g' is missing in type '{ f: (n: number) => number; m: number; }' but required in type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'.
assignmentCompatBug2.ts(33,1): error TS2741: Property 'm' is missing in type '{ f: (n: number) => number; g: (s: string) => number; n: number; k: (a: any) => any; }' but required in type '{ f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; }'.
Expand All @@ -12,18 +9,15 @@ assignmentCompatBug2.ts(33,1): error TS2741: Property 'm' is missing in type '{
==== assignmentCompatBug2.ts (6 errors) ====
var b2: { b: number;} = { a: 0 }; // error
~
!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ b: number; }'.
!!! error TS2322: Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.
!!! error TS2353: Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.

b2 = { a: 0 }; // error
~
!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ b: number; }'.
!!! error TS2322: Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.
!!! error TS2353: Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.

b2 = {b: 0, a: 0 };
~
!!! error TS2322: Type '{ b: number; a: number; }' is not assignable to type '{ b: number; }'.
!!! error TS2322: Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.
!!! error TS2353: Object literal may only specify known properties, and 'a' does not exist in type '{ b: number; }'.

var b3: { f(n: number): number; g(s: string): number; m: number; n?: number; k?(a: any): any; };

Expand Down
6 changes: 2 additions & 4 deletions tests/baselines/reference/assignmentCompatBug5.errors.txt
@@ -1,5 +1,4 @@
assignmentCompatBug5.ts(2,8): error TS2345: Argument of type '{ b: number; }' is not assignable to parameter of type '{ a: number; }'.
Object literal may only specify known properties, and 'b' does not exist in type '{ a: number; }'.
assignmentCompatBug5.ts(2,8): error TS2353: Object literal may only specify known properties, and 'b' does not exist in type '{ a: number; }'.
assignmentCompatBug5.ts(5,7): error TS2322: Type 'string' is not assignable to type 'number'.
assignmentCompatBug5.ts(5,12): error TS2322: Type 'string' is not assignable to type 'number'.
assignmentCompatBug5.ts(8,6): error TS2345: Argument of type '(s: string) => void' is not assignable to parameter of type '(n: number) => number'.
Expand All @@ -13,8 +12,7 @@ assignmentCompatBug5.ts(9,6): error TS2345: Argument of type '(n: number) => voi
function foo1(x: { a: number; }) { }
foo1({ b: 5 });
~
!!! error TS2345: Argument of type '{ b: number; }' is not assignable to parameter of type '{ a: number; }'.
!!! error TS2345: Object literal may only specify known properties, and 'b' does not exist in type '{ a: number; }'.
!!! error TS2353: Object literal may only specify known properties, and 'b' does not exist in type '{ a: number; }'.

function foo2(x: number[]) { }
foo2(["s", "t"]);
Expand Down
12 changes: 4 additions & 8 deletions tests/baselines/reference/checkJsdocSatisfiesTag1.errors.txt
@@ -1,9 +1,7 @@
/a.js(21,44): error TS1360: Type '{ a: number; b: number; }' does not satisfy the expected type 'T1'.
Object literal may only specify known properties, and 'b' does not exist in type 'T1'.
/a.js(21,44): error TS2353: Object literal may only specify known properties, and 'b' does not exist in type 'T1'.
/a.js(22,17): error TS1360: Type '{}' does not satisfy the expected type 'T1'.
Property 'a' is missing in type '{}' but required in type 'T1'.
/a.js(31,49): error TS1360: Type '{ a: string; b: string; }' does not satisfy the expected type 'T4'.
Object literal may only specify known properties, and 'b' does not exist in type 'T4'.
/a.js(31,49): error TS2353: Object literal may only specify known properties, and 'b' does not exist in type 'T4'.


==== /a.js (3 errors) ====
Expand All @@ -29,8 +27,7 @@
const t1 = /** @satisfies {T1} */ ({ a: 1 });
const t2 = /** @satisfies {T1} */ ({ a: 1, b: 1 });
~
!!! error TS1360: Type '{ a: number; b: number; }' does not satisfy the expected type 'T1'.
!!! error TS1360: Object literal may only specify known properties, and 'b' does not exist in type 'T1'.
!!! error TS2353: Object literal may only specify known properties, and 'b' does not exist in type 'T1'.
const t3 = /** @satisfies {T1} */ ({});
~~~~~~~~~
!!! error TS1360: Type '{}' does not satisfy the expected type 'T1'.
Expand All @@ -46,6 +43,5 @@
const t7 = /** @satisfies {T4} */ ({ a: 'test' });
const t8 = /** @satisfies {T4} */ ({ a: 'test', b: 'test' });
~
!!! error TS1360: Type '{ a: string; b: string; }' does not satisfy the expected type 'T4'.
!!! error TS1360: Object literal may only specify known properties, and 'b' does not exist in type 'T4'.
!!! error TS2353: Object literal may only specify known properties, and 'b' does not exist in type 'T4'.

6 changes: 2 additions & 4 deletions tests/baselines/reference/checkJsdocSatisfiesTag10.errors.txt
@@ -1,5 +1,4 @@
/a.js(6,5): error TS1360: Type '{ a: number; b: string; x: number; }' does not satisfy the expected type 'Partial<Record<Keys, unknown>>'.
Object literal may only specify known properties, and 'x' does not exist in type 'Partial<Record<Keys, unknown>>'.
/a.js(6,5): error TS2353: Object literal may only specify known properties, and 'x' does not exist in type 'Partial<Record<Keys, unknown>>'.
/a.js(14,11): error TS2339: Property 'd' does not exist on type '{ a: number; b: string; x: number; }'.


Expand All @@ -11,8 +10,7 @@
b: "hello",
x: 8 // Should error, 'x' isn't in 'Keys'
~
!!! error TS1360: Type '{ a: number; b: string; x: number; }' does not satisfy the expected type 'Partial<Record<Keys, unknown>>'.
!!! error TS1360: Object literal may only specify known properties, and 'x' does not exist in type 'Partial<Record<Keys, unknown>>'.
!!! error TS2353: Object literal may only specify known properties, and 'x' does not exist in type 'Partial<Record<Keys, unknown>>'.
});

// Should be OK -- retain info that a is number and b is string
Expand Down
12 changes: 4 additions & 8 deletions tests/baselines/reference/checkJsdocSatisfiesTag12.errors.txt
@@ -1,7 +1,5 @@
/a.js(24,20): error TS1360: Type '{ a: number; b: number; }' does not satisfy the expected type 'T1'.
Object literal may only specify known properties, and 'b' does not exist in type 'T1'.
/a.js(44,25): error TS1360: Type '{ a: string; b: string; }' does not satisfy the expected type 'T2'.
Object literal may only specify known properties, and 'b' does not exist in type 'T2'.
/a.js(24,20): error TS2353: Object literal may only specify known properties, and 'b' does not exist in type 'T1'.
/a.js(44,25): error TS2353: Object literal may only specify known properties, and 'b' does not exist in type 'T2'.
/a.js(51,6): error TS1360: Type 'number' does not satisfy the expected type 'string'.


Expand Down Expand Up @@ -31,8 +29,7 @@
*/
const t2 = { a: 1, b: 1 };
~
!!! error TS1360: Type '{ a: number; b: number; }' does not satisfy the expected type 'T1'.
!!! error TS1360: Object literal may only specify known properties, and 'b' does not exist in type 'T1'.
!!! error TS2353: Object literal may only specify known properties, and 'b' does not exist in type 'T1'.

/**
* @satisfies {T1}
Expand All @@ -54,8 +51,7 @@
*/
const t6 = { a: 'test', b: 'test' };
~
!!! error TS1360: Type '{ a: string; b: string; }' does not satisfy the expected type 'T2'.
!!! error TS1360: Object literal may only specify known properties, and 'b' does not exist in type 'T2'.
!!! error TS2353: Object literal may only specify known properties, and 'b' does not exist in type 'T2'.

/**
* @satisfies {T3}
Expand Down

0 comments on commit 9a771d5

Please sign in to comment.