Skip to content

Commit 355125d

Browse files
authored
Report errors in JSX properties on the failing prop or the tag name (#23148)
1 parent 5f9c34b commit 355125d

File tree

50 files changed

+427
-558
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+427
-558
lines changed

src/compiler/checker.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16194,7 +16194,7 @@ namespace ts {
1619416194
const sourceAttributesType = createJsxAttributesTypeFromAttributesProperty(openingLikeElement, checkMode);
1619516195

1619616196
// Check if sourceAttributesType assignable to targetAttributesType though this check will allow excess properties
16197-
const isSourceAttributeTypeAssignableToTarget = checkTypeAssignableTo(sourceAttributesType, targetAttributesType, openingLikeElement.attributes.properties.length > 0 ? openingLikeElement.attributes : openingLikeElement);
16197+
const isSourceAttributeTypeAssignableToTarget = isTypeAssignableTo(sourceAttributesType, targetAttributesType);
1619816198
// After we check for assignability, we will do another pass to check that all explicitly specified attributes have correct name corresponding in targetAttributeType.
1619916199
// This will allow excess properties in spread type as it is very common pattern to spread outer attributes into React component in its render method.
1620016200
if (isSourceAttributeTypeAssignableToTarget && !isTypeAny(sourceAttributesType) && !isTypeAny(targetAttributesType)) {
@@ -16211,6 +16211,32 @@ namespace ts {
1621116211
}
1621216212
}
1621316213
}
16214+
else if (!isSourceAttributeTypeAssignableToTarget) {
16215+
// Assignability failure - check each prop individually, and if that fails, fall back on the bad error span
16216+
if (length(openingLikeElement.attributes.properties)) {
16217+
let reportedError = false;
16218+
for (const prop of openingLikeElement.attributes.properties) {
16219+
if (isJsxSpreadAttribute(prop)) continue;
16220+
const name = idText(prop.name);
16221+
const sourcePropType = getIndexedAccessType(sourceAttributesType, getLiteralType(name));
16222+
const targetPropType = getIndexedAccessType(targetAttributesType, getLiteralType(name));
16223+
const rootChain = () => chainDiagnosticMessages(
16224+
/*details*/ undefined,
16225+
Diagnostics.Types_of_property_0_are_incompatible,
16226+
name,
16227+
);
16228+
if (!checkTypeAssignableTo(sourcePropType, targetPropType, prop, /*headMessage*/ undefined, rootChain)) {
16229+
reportedError = true;
16230+
}
16231+
}
16232+
16233+
if (reportedError) {
16234+
return;
16235+
}
16236+
}
16237+
// Report fallback error on just the component name
16238+
checkTypeAssignableTo(sourceAttributesType, targetAttributesType, openingLikeElement.tagName);
16239+
}
1621416240
}
1621516241

1621616242
function checkJsxExpression(node: JsxExpression, checkMode?: CheckMode) {

tests/baselines/reference/checkJsxChildrenProperty14.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/conformance/jsx/file.tsx(42,27): error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
1+
tests/cases/conformance/jsx/file.tsx(42,11): error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
22
Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'SingleChildProp'.
33
Types of property 'children' are incompatible.
44
Type 'Element[]' is not assignable to type 'Element'.
@@ -48,7 +48,7 @@ tests/cases/conformance/jsx/file.tsx(42,27): error TS2322: Type '{ children: Ele
4848

4949
// Error
5050
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
51-
~~~~~~~~~~~~~
51+
~~~~~~~~~~~~~~~
5252
!!! error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
5353
!!! error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'SingleChildProp'.
5454
!!! error TS2322: Types of property 'children' are incompatible.

tests/baselines/reference/checkJsxChildrenProperty2.errors.txt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
tests/cases/conformance/jsx/file.tsx(14,15): error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
1+
tests/cases/conformance/jsx/file.tsx(14,10): error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
22
Type '{ a: number; b: string; }' is not assignable to type 'Prop'.
33
Property 'children' is missing in type '{ a: number; b: string; }'.
44
tests/cases/conformance/jsx/file.tsx(17,11): error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten.
5-
tests/cases/conformance/jsx/file.tsx(31,11): error TS2322: Type '{ children: (Element | ((name: string) => Element))[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
5+
tests/cases/conformance/jsx/file.tsx(31,6): error TS2322: Type '{ children: (Element | ((name: string) => Element))[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
66
Type '{ children: (Element | ((name: string) => Element))[]; a: number; b: string; }' is not assignable to type 'Prop'.
77
Types of property 'children' are incompatible.
88
Type '(Element | ((name: string) => Element))[]' is not assignable to type 'string | Element'.
99
Type '(Element | ((name: string) => Element))[]' is not assignable to type 'Element'.
1010
Property 'type' is missing in type '(Element | ((name: string) => Element))[]'.
11-
tests/cases/conformance/jsx/file.tsx(37,11): error TS2322: Type '{ children: (number | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
11+
tests/cases/conformance/jsx/file.tsx(37,6): error TS2322: Type '{ children: (number | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
1212
Type '{ children: (number | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
1313
Types of property 'children' are incompatible.
1414
Type '(number | Element)[]' is not assignable to type 'string | Element'.
1515
Type '(number | Element)[]' is not assignable to type 'Element'.
1616
Property 'type' is missing in type '(number | Element)[]'.
17-
tests/cases/conformance/jsx/file.tsx(43,11): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
17+
tests/cases/conformance/jsx/file.tsx(43,6): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
1818
Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
1919
Types of property 'children' are incompatible.
2020
Type '(string | Element)[]' is not assignable to type 'string | Element'.
2121
Type '(string | Element)[]' is not assignable to type 'Element'.
2222
Property 'type' is missing in type '(string | Element)[]'.
23-
tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
23+
tests/cases/conformance/jsx/file.tsx(49,6): error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
2424
Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'Prop'.
2525
Types of property 'children' are incompatible.
2626
Type 'Element[]' is not assignable to type 'string | Element'.
@@ -43,7 +43,7 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ children: Ele
4343

4444
// Error: missing children
4545
let k = <Comp a={10} b="hi" />;
46-
~~~~~~~~~~~~~
46+
~~~~
4747
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
4848
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'Prop'.
4949
!!! error TS2322: Property 'children' is missing in type '{ a: number; b: string; }'.
@@ -66,7 +66,7 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ children: Ele
6666
// Error: incorrect type
6767
let k2 =
6868
<Comp a={10} b="hi">
69-
~~~~~~~~~~~~~
69+
~~~~
7070
!!! error TS2322: Type '{ children: (Element | ((name: string) => Element))[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
7171
!!! error TS2322: Type '{ children: (Element | ((name: string) => Element))[]; a: number; b: string; }' is not assignable to type 'Prop'.
7272
!!! error TS2322: Types of property 'children' are incompatible.
@@ -79,7 +79,7 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ children: Ele
7979

8080
let k3 =
8181
<Comp a={10} b="hi">
82-
~~~~~~~~~~~~~
82+
~~~~
8383
!!! error TS2322: Type '{ children: (number | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
8484
!!! error TS2322: Type '{ children: (number | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
8585
!!! error TS2322: Types of property 'children' are incompatible.
@@ -92,7 +92,7 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ children: Ele
9292

9393
let k4 =
9494
<Comp a={10} b="hi" >
95-
~~~~~~~~~~~~~
95+
~~~~
9696
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
9797
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
9898
!!! error TS2322: Types of property 'children' are incompatible.
@@ -105,7 +105,7 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ children: Ele
105105

106106
let k5 =
107107
<Comp a={10} b="hi" >
108-
~~~~~~~~~~~~~
108+
~~~~
109109
!!! error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
110110
!!! error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'Prop'.
111111
!!! error TS2322: Types of property 'children' are incompatible.

tests/baselines/reference/checkJsxChildrenProperty4.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/conformance/jsx/file.tsx(24,28): error TS2551: Property 'NAme' does not exist on type 'IUser'. Did you mean 'Name'?
2-
tests/cases/conformance/jsx/file.tsx(32,9): error TS2322: Type '{ children: ((user: IUser) => Element)[]; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<FetchUser> & IFetchUserProps & { children?: ReactNode; }'.
2+
tests/cases/conformance/jsx/file.tsx(32,10): error TS2322: Type '{ children: ((user: IUser) => Element)[]; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<FetchUser> & IFetchUserProps & { children?: ReactNode; }'.
33
Type '{ children: ((user: IUser) => Element)[]; }' is not assignable to type 'IFetchUserProps'.
44
Types of property 'children' are incompatible.
55
Type '((user: IUser) => Element)[]' is not assignable to type '(user: IUser) => Element'.
@@ -41,7 +41,7 @@ tests/cases/conformance/jsx/file.tsx(32,9): error TS2322: Type '{ children: ((us
4141
function UserName1() {
4242
return (
4343
<FetchUser>
44-
~~~~~~~~~~~
44+
~~~~~~~~~
4545
!!! error TS2322: Type '{ children: ((user: IUser) => Element)[]; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<FetchUser> & IFetchUserProps & { children?: ReactNode; }'.
4646
!!! error TS2322: Type '{ children: ((user: IUser) => Element)[]; }' is not assignable to type 'IFetchUserProps'.
4747
!!! error TS2322: Types of property 'children' are incompatible.

tests/baselines/reference/checkJsxChildrenProperty5.errors.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
tests/cases/conformance/jsx/file.tsx(20,15): error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
1+
tests/cases/conformance/jsx/file.tsx(20,10): error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
22
Type '{ a: number; b: string; }' is not assignable to type 'Prop'.
33
Property 'children' is missing in type '{ a: number; b: string; }'.
4-
tests/cases/conformance/jsx/file.tsx(24,11): error TS2322: Type '{ children: Element; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
4+
tests/cases/conformance/jsx/file.tsx(24,6): error TS2322: Type '{ children: Element; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
55
Type '{ children: Element; a: number; b: string; }' is not assignable to type 'Prop'.
66
Types of property 'children' are incompatible.
77
Type 'Element' is not assignable to type 'Button'.
88
Property 'render' is missing in type 'Element'.
9-
tests/cases/conformance/jsx/file.tsx(28,11): error TS2322: Type '{ children: typeof Button; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
9+
tests/cases/conformance/jsx/file.tsx(28,6): error TS2322: Type '{ children: typeof Button; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
1010
Type '{ children: typeof Button; a: number; b: string; }' is not assignable to type 'Prop'.
1111
Types of property 'children' are incompatible.
1212
Type 'typeof Button' is not assignable to type 'Button'.
@@ -34,15 +34,15 @@ tests/cases/conformance/jsx/file.tsx(28,11): error TS2322: Type '{ children: typ
3434

3535
// Error: no children specified
3636
let k = <Comp a={10} b="hi" />;
37-
~~~~~~~~~~~~~
37+
~~~~
3838
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
3939
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'Prop'.
4040
!!! error TS2322: Property 'children' is missing in type '{ a: number; b: string; }'.
4141

4242
// Error: JSX.element is not the same as JSX.ElementClass
4343
let k1 =
4444
<Comp a={10} b="hi">
45-
~~~~~~~~~~~~~
45+
~~~~
4646
!!! error TS2322: Type '{ children: Element; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
4747
!!! error TS2322: Type '{ children: Element; a: number; b: string; }' is not assignable to type 'Prop'.
4848
!!! error TS2322: Types of property 'children' are incompatible.
@@ -52,7 +52,7 @@ tests/cases/conformance/jsx/file.tsx(28,11): error TS2322: Type '{ children: typ
5252
</Comp>;
5353
let k2 =
5454
<Comp a={10} b="hi">
55-
~~~~~~~~~~~~~
55+
~~~~
5656
!!! error TS2322: Type '{ children: typeof Button; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
5757
!!! error TS2322: Type '{ children: typeof Button; a: number; b: string; }' is not assignable to type 'Prop'.
5858
!!! error TS2322: Types of property 'children' are incompatible.

tests/baselines/reference/checkJsxChildrenProperty7.errors.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
tests/cases/conformance/jsx/file.tsx(24,16): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
1+
tests/cases/conformance/jsx/file.tsx(24,11): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
22
Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
33
Types of property 'children' are incompatible.
44
Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
55
Type '(string | Element)[]' is not assignable to type 'Element[]'.
66
Type 'string | Element' is not assignable to type 'Element'.
77
Type 'string' is not assignable to type 'Element'.
8-
tests/cases/conformance/jsx/file.tsx(25,16): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
8+
tests/cases/conformance/jsx/file.tsx(25,11): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
99
Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
1010
Types of property 'children' are incompatible.
1111
Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
1212
Type '(string | Element)[]' is not assignable to type 'Element[]'.
13-
tests/cases/conformance/jsx/file.tsx(27,16): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
13+
tests/cases/conformance/jsx/file.tsx(27,11): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
1414
Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
1515
Types of property 'children' are incompatible.
1616
Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
@@ -42,7 +42,7 @@ tests/cases/conformance/jsx/file.tsx(27,16): error TS2322: Type '{ children: (st
4242

4343
// Error: whitespaces matters
4444
let k1 = <Comp a={10} b="hi"><Button /> <AnotherButton /></Comp>;
45-
~~~~~~~~~~~~~
45+
~~~~
4646
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
4747
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
4848
!!! error TS2322: Types of property 'children' are incompatible.
@@ -51,15 +51,15 @@ tests/cases/conformance/jsx/file.tsx(27,16): error TS2322: Type '{ children: (st
5151
!!! error TS2322: Type 'string | Element' is not assignable to type 'Element'.
5252
!!! error TS2322: Type 'string' is not assignable to type 'Element'.
5353
let k2 = <Comp a={10} b="hi"><Button />
54-
~~~~~~~~~~~~~
54+
~~~~
5555
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
5656
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
5757
!!! error TS2322: Types of property 'children' are incompatible.
5858
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
5959
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element[]'.
6060
<AnotherButton /> </Comp>;
6161
let k3 = <Comp a={10} b="hi"> <Button />
62-
~~~~~~~~~~~~~
62+
~~~~
6363
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
6464
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
6565
!!! error TS2322: Types of property 'children' are incompatible.

0 commit comments

Comments
 (0)