Skip to content

Commit cd37e41

Browse files
authored
Make finer-grained errors get reported on function arguments (#26784)
1 parent 2deb318 commit cd37e41

File tree

33 files changed

+257
-395
lines changed

33 files changed

+257
-395
lines changed

src/compiler/checker.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -10528,9 +10528,13 @@ namespace ts {
1052810528
* attempt to issue more specific errors on, for example, specific object literal properties or tuple members.
1052910529
*/
1053010530
function checkTypeAssignableToAndOptionallyElaborate(source: Type, target: Type, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean {
10531-
if (isTypeAssignableTo(source, target)) return true;
10532-
if (!elaborateError(expr, source, target)) {
10533-
return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain);
10531+
return checkTypeRelatedToAndOptionallyElaborate(source, target, assignableRelation, errorNode, expr, headMessage, containingMessageChain);
10532+
}
10533+
10534+
function checkTypeRelatedToAndOptionallyElaborate(source: Type, target: Type, relation: Map<RelationComparisonResult>, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean {
10535+
if (isTypeRelatedTo(source, target, relation)) return true;
10536+
if (!errorNode || !elaborateError(expr, source, target)) {
10537+
return checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain);
1053410538
}
1053510539
return false;
1053610540
}
@@ -18869,7 +18873,7 @@ namespace ts {
1886918873
// we obtain the regular type of any object literal arguments because we may not have inferred complete
1887018874
// parameter types yet and therefore excess property checks may yield false positives (see #17041).
1887118875
const checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType;
18872-
if (!checkTypeRelatedTo(checkArgType, paramType, relation, reportErrors ? arg : undefined, headMessage)) {
18876+
if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage)) {
1887318877
return false;
1887418878
}
1887518879
}

tests/baselines/reference/assignmentCompatFunctionsWithOptionalArgs.errors.txt

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(1,10): error TS2391: Function implementation is missing or not immediately following the declaration.
2-
tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(4,5): error TS2345: Argument of type '{ id: number; name: boolean; }' is not assignable to parameter of type '{ id: number; name?: string; }'.
3-
Types of property 'name' are incompatible.
4-
Type 'boolean' is not assignable to type 'string'.
2+
tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(4,17): error TS2322: Type 'false' is not assignable to type 'string'.
53
tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(5,5): error TS2345: Argument of type '{ name: string; }' is not assignable to parameter of type '{ id: number; name?: string; }'.
64
Property 'id' is missing in type '{ name: string; }'.
75

@@ -13,10 +11,9 @@ tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(5,5): error TS
1311
foo({ id: 1234 }); // Ok
1412
foo({ id: 1234, name: "hello" }); // Ok
1513
foo({ id: 1234, name: false }); // Error, name of wrong type
16-
~~~~~~~~~~~~~~~~~~~~~~~~~
17-
!!! error TS2345: Argument of type '{ id: number; name: boolean; }' is not assignable to parameter of type '{ id: number; name?: string; }'.
18-
!!! error TS2345: Types of property 'name' are incompatible.
19-
!!! error TS2345: Type 'boolean' is not assignable to type 'string'.
14+
~~~~
15+
!!! error TS2322: Type 'false' is not assignable to type 'string'.
16+
!!! related TS6500 tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts:1:31: The expected type comes from property 'name' which is declared here on type '{ id: number; name?: string; }'
2017
foo({ name: "hello" }); // Error, id required but missing
2118
~~~~~~~~~~~~~~~~~
2219
!!! error TS2345: Argument of type '{ name: string; }' is not assignable to parameter of type '{ id: number; name?: string; }'.

tests/baselines/reference/declarationsAndAssignments.errors.txt

+5-9
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(73,11):
1717
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(73,14): error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
1818
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,11): error TS2459: Type 'undefined[]' has no property 'a' and no string index signature.
1919
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,14): error TS2459: Type 'undefined[]' has no property 'b' and no string index signature.
20-
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(106,5): error TS2345: Argument of type '[number, [string, { y: false; }]]' is not assignable to parameter of type '[number, [string, { x: any; y?: boolean; }]]'.
21-
Type '[string, { y: false; }]' is not assignable to type '[string, { x: any; y?: boolean; }]'.
22-
Type '{ y: false; }' is not assignable to type '{ x: any; y?: boolean; }'.
23-
Property 'x' is missing in type '{ y: false; }'.
20+
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(106,17): error TS2322: Type '{ y: boolean; }' is not assignable to type '{ x: any; y?: boolean; }'.
21+
Property 'x' is missing in type '{ y: boolean; }'.
2422
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,6): error TS2322: Type 'string' is not assignable to type 'number'.
2523
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,9): error TS2322: Type 'number' is not assignable to type 'string'.
2624

@@ -170,11 +168,9 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,9):
170168
f14([2, ["abc", { x: 0, y: true }]]);
171169
f14([2, ["abc", { x: 0 }]]);
172170
f14([2, ["abc", { y: false }]]); // Error, no x
173-
~~~~~~~~~~~~~~~~~~~~~~~~~~
174-
!!! error TS2345: Argument of type '[number, [string, { y: false; }]]' is not assignable to parameter of type '[number, [string, { x: any; y?: boolean; }]]'.
175-
!!! error TS2345: Type '[string, { y: false; }]' is not assignable to type '[string, { x: any; y?: boolean; }]'.
176-
!!! error TS2345: Type '{ y: false; }' is not assignable to type '{ x: any; y?: boolean; }'.
177-
!!! error TS2345: Property 'x' is missing in type '{ y: false; }'.
171+
~~~~~~~~~~~~
172+
!!! error TS2322: Type '{ y: boolean; }' is not assignable to type '{ x: any; y?: boolean; }'.
173+
!!! error TS2322: Property 'x' is missing in type '{ y: boolean; }'.
178174

179175
module M {
180176
export var [a, b] = [1, 2];

tests/baselines/reference/destructuringParameterDeclaration2.errors.txt

+27-58
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,21 @@
1-
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(7,4): error TS2345: Argument of type '[number, string, string[][]]' is not assignable to parameter of type '[number, number, string[][]]'.
2-
Type 'string' is not assignable to type 'number'.
1+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(7,8): error TS2322: Type 'string' is not assignable to type 'number'.
32
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(7,29): error TS1005: ',' expected.
43
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(8,4): error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'.
54
Types of property 'length' are incompatible.
65
Type '4' is not assignable to type '3'.
76
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(16,8): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
87
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(16,16): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
9-
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(23,14): error TS2345: Argument of type '{ x: string; y: boolean; }' is not assignable to parameter of type '{ x: number; y: any; }'.
10-
Types of property 'x' are incompatible.
11-
Type 'string' is not assignable to type 'number'.
8+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(23,16): error TS2322: Type 'string' is not assignable to type 'number'.
129
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(30,14): error TS2300: Duplicate identifier 'z'.
1310
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(30,18): error TS2300: Duplicate identifier 'z'.
14-
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(34,4): error TS2345: Argument of type '{ z: number; }' is not assignable to parameter of type '{ z: { x: any; y: { j: any; }; }; }'.
15-
Types of property 'z' are incompatible.
16-
Type 'number' is not assignable to type '{ x: any; y: { j: any; }; }'.
11+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(34,6): error TS2322: Type 'number' is not assignable to type '{ x: any; y: { j: any; }; }'.
1712
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(35,4): error TS2345: Argument of type '{}' is not assignable to parameter of type '{ z: number; }'.
1813
Property 'z' is missing in type '{}'.
19-
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(36,4): error TS2345: Argument of type '{ z: boolean; }' is not assignable to parameter of type '{ z: number; }'.
20-
Types of property 'z' are incompatible.
21-
Type 'boolean' is not assignable to type 'number'.
22-
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(37,4): error TS2345: Argument of type '{ z: boolean; }' is not assignable to parameter of type '{ z?: number; }'.
23-
Types of property 'z' are incompatible.
24-
Type 'boolean' is not assignable to type 'number'.
25-
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(38,4): error TS2345: Argument of type '{ b: boolean; }' is not assignable to parameter of type '{ b: string | number; }'.
26-
Types of property 'b' are incompatible.
27-
Type 'boolean' is not assignable to type 'string | number'.
28-
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(39,4): error TS2345: Argument of type '[number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
29-
Types of property '2' are incompatible.
30-
Type 'boolean' is not assignable to type '[[any]]'.
31-
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(40,4): error TS2345: Argument of type '[number, number, [[string]]]' is not assignable to parameter of type '[any, any, [[number?]]]'.
32-
Type '[[string]]' is not assignable to type '[[number?]]'.
33-
Type '[string]' is not assignable to type '[number?]'.
34-
Types of property '0' are incompatible.
35-
Type 'string' is not assignable to type 'number'.
14+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(36,6): error TS2322: Type 'true' is not assignable to type 'number'.
15+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(37,6): error TS2322: Type 'false' is not assignable to type 'number'.
16+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(38,6): error TS2322: Type 'true' is not assignable to type 'string | number'.
17+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(39,11): error TS2322: Type 'false' is not assignable to type '[[any]]'.
18+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(40,13): error TS2322: Type 'string' is not assignable to type 'number'.
3619
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(46,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature.
3720
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(47,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature.
3821
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(56,8): error TS2463: A binding pattern parameter cannot be optional in an implementation signature.
@@ -54,9 +37,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(
5437
// If the declaration includes a type annotation, the parameter is of that type
5538
function a0([a, b, [[c]]]: [number, number, string[][]]) { }
5639
a0([1, "string", [["world"]]); // Error
57-
~~~~~~~~~~~~~~~~~~~~~~~~~
58-
!!! error TS2345: Argument of type '[number, string, string[][]]' is not assignable to parameter of type '[number, number, string[][]]'.
59-
!!! error TS2345: Type 'string' is not assignable to type 'number'.
40+
~~~~~~~~
41+
!!! error TS2322: Type 'string' is not assignable to type 'number'.
6042
~
6143
!!! error TS1005: ',' expected.
6244
a0([1, 2, [["world"]], "string"]); // Error
@@ -83,10 +65,9 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(
8365
function b3([[a], b, [[c, d]]] = [[undefined], undefined, [[undefined, undefined]]]) { }
8466

8567
b1("string", { x: "string", y: true }); // Error
86-
~~~~~~~~~~~~~~~~~~~~~~~~
87-
!!! error TS2345: Argument of type '{ x: string; y: boolean; }' is not assignable to parameter of type '{ x: number; y: any; }'.
88-
!!! error TS2345: Types of property 'x' are incompatible.
89-
!!! error TS2345: Type 'string' is not assignable to type 'number'.
68+
~
69+
!!! error TS2322: Type 'string' is not assignable to type 'number'.
70+
!!! related TS6500 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts:19:29: The expected type comes from property 'x' which is declared here on type '{ x: number; y: any; }'
9071

9172
// If the declaration specifies a binding pattern, the parameter type is the implied type of that binding pattern (section 5.1.3)
9273
function c0({z: {x, y: {j}}}) { }
@@ -102,41 +83,29 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(
10283
function c6([a, b, [[c = 1]]]) { }
10384

10485
c0({ z: 1 }); // Error, implied type is { z: {x: any, y: {j: any}} }
105-
~~~~~~~~
106-
!!! error TS2345: Argument of type '{ z: number; }' is not assignable to parameter of type '{ z: { x: any; y: { j: any; }; }; }'.
107-
!!! error TS2345: Types of property 'z' are incompatible.
108-
!!! error TS2345: Type 'number' is not assignable to type '{ x: any; y: { j: any; }; }'.
86+
~
87+
!!! error TS2322: Type 'number' is not assignable to type '{ x: any; y: { j: any; }; }'.
10988
c1({}); // Error, implied type is {z:number}?
11089
~~
11190
!!! error TS2345: Argument of type '{}' is not assignable to parameter of type '{ z: number; }'.
11291
!!! error TS2345: Property 'z' is missing in type '{}'.
11392
c1({ z: true }); // Error, implied type is {z:number}?
114-
~~~~~~~~~~~
115-
!!! error TS2345: Argument of type '{ z: boolean; }' is not assignable to parameter of type '{ z: number; }'.
116-
!!! error TS2345: Types of property 'z' are incompatible.
117-
!!! error TS2345: Type 'boolean' is not assignable to type 'number'.
93+
~
94+
!!! error TS2322: Type 'true' is not assignable to type 'number'.
95+
!!! related TS6500 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts:27:21: The expected type comes from property 'z' which is declared here on type '{ z: number; }'
11896
c2({ z: false }); // Error, implied type is {z?: number}
119-
~~~~~~~~~~~~
120-
!!! error TS2345: Argument of type '{ z: boolean; }' is not assignable to parameter of type '{ z?: number; }'.
121-
!!! error TS2345: Types of property 'z' are incompatible.
122-
!!! error TS2345: Type 'boolean' is not assignable to type 'number'.
97+
~
98+
!!! error TS2322: Type 'false' is not assignable to type 'number'.
12399
c3({ b: true }); // Error, implied type is { b: number|string }.
124-
~~~~~~~~~~~
125-
!!! error TS2345: Argument of type '{ b: boolean; }' is not assignable to parameter of type '{ b: string | number; }'.
126-
!!! error TS2345: Types of property 'b' are incompatible.
127-
!!! error TS2345: Type 'boolean' is not assignable to type 'string | number'.
100+
~
101+
!!! error TS2322: Type 'true' is not assignable to type 'string | number'.
102+
!!! related TS6500 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts:29:20: The expected type comes from property 'b' which is declared here on type '{ b: string | number; }'
128103
c5([1, 2, false, true]); // Error, implied type is [any, any, [[any]]]
129-
~~~~~~~~~~~~~~~~~~~
130-
!!! error TS2345: Argument of type '[number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
131-
!!! error TS2345: Types of property '2' are incompatible.
132-
!!! error TS2345: Type 'boolean' is not assignable to type '[[any]]'.
104+
~~~~~
105+
!!! error TS2322: Type 'false' is not assignable to type '[[any]]'.
133106
c6([1, 2, [["string"]]]); // Error, implied type is [any, any, [[number]]] // Use initializer
134-
~~~~~~~~~~~~~~~~~~~~
135-
!!! error TS2345: Argument of type '[number, number, [[string]]]' is not assignable to parameter of type '[any, any, [[number?]]]'.
136-
!!! error TS2345: Type '[[string]]' is not assignable to type '[[number?]]'.
137-
!!! error TS2345: Type '[string]' is not assignable to type '[number?]'.
138-
!!! error TS2345: Types of property '0' are incompatible.
139-
!!! error TS2345: Type 'string' is not assignable to type 'number'.
107+
~~~~~~~~
108+
!!! error TS2322: Type 'string' is not assignable to type 'number'.
140109

141110
// A parameter can be marked optional by following its name or binding pattern with a question mark (?)
142111
// or by including an initializer. Initializers (including binding property or element initializers) are

tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
22
Types of property 'length' are incompatible.
33
Type '5' is not assignable to type '3'.
4-
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(29,5): error TS2345: Argument of type '[number, number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'.
5-
Types of property '2' are incompatible.
6-
Type 'number' is not assignable to type '[[any]]'.
4+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(29,12): error TS2322: Type 'number' is not assignable to type '[[any]]'.
75
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(30,5): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'.
86
Property '2' is missing in type '[number, number]'.
97

@@ -42,10 +40,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.
4240

4341
a10([1, 2, [["string"]], false, true]); // Parameter type is any[]
4442
a10([1, 2, 3, false, true]); // Parameter type is any[]
45-
~~~~~~~~~~~~~~~~~~~~~~
46-
!!! error TS2345: Argument of type '[number, number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'.
47-
!!! error TS2345: Types of property '2' are incompatible.
48-
!!! error TS2345: Type 'number' is not assignable to type '[[any]]'.
43+
~
44+
!!! error TS2322: Type 'number' is not assignable to type '[[any]]'.
4945
a10([1, 2]); // Parameter type is any[]
5046
~~~~~~
5147
!!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'.

0 commit comments

Comments
 (0)