Skip to content

Commit dbc1722

Browse files
author
Nathan Fenner
committed
report extraneous jsx attribute error on attribute name instead of entire attribute assignment
1 parent 9402317 commit dbc1722

12 files changed

+22
-27
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13040,15 +13040,10 @@ namespace ts {
1304013040
// JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal.
1304113041
// However, using an object-literal error message will be very confusing to the users so we give different a message.
1304213042
// TODO: Spelling suggestions for excess jsx attributes (needs new diagnostic messages)
13043-
13044-
if (errorNode && isJsxOpeningLikeElement(errorNode.parent)) {
13045-
const attributes = errorNode.parent.attributes;
13046-
for (const jsxProperty of attributes.properties) {
13047-
if (jsxProperty.kind === SyntaxKind.JsxAttribute && jsxProperty.name.escapedText === prop.escapedName) {
13048-
// Move the error node to the actual JSX property, instead of pointing to the identifier in the JSX element.
13049-
errorNode = jsxProperty;
13050-
}
13051-
}
13043+
if (prop.valueDeclaration && isNamedDeclaration(prop.valueDeclaration) && prop.valueDeclaration.name && prop.valueDeclaration.name.pos !== -1) {
13044+
// If the "children" attribute is extraneous `<NoChild>extra</NoChild>` then the declaration's name has no location.
13045+
// In that case, do not update the error location, since there's no name to point to.
13046+
errorNode = prop.valueDeclaration.name;
1305213047
}
1305313048
reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(errorTarget));
1305413049
}

tests/baselines/reference/tsxAttributeResolution1.errors.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,19 @@ tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type 'number' is not a
3838
!!! error TS2322: Type 'string' is not assignable to type 'number'.
3939
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:10:2: The expected type comes from property 'x' which is declared here on type 'Attribs1'
4040
<test1 y={0} />; // Error, no property "y"
41-
~~~~~
41+
~
4242
!!! error TS2322: Type '{ y: number; }' is not assignable to type 'Attribs1'.
4343
!!! error TS2322: Property 'y' does not exist on type 'Attribs1'.
4444
<test1 y="foo" />; // Error, no property "y"
45-
~~~~~~~
45+
~
4646
!!! error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'.
4747
!!! error TS2322: Property 'y' does not exist on type 'Attribs1'.
4848
<test1 x="32" />; // Error, "32" is not number
4949
~
5050
!!! error TS2322: Type 'string' is not assignable to type 'number'.
5151
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:10:2: The expected type comes from property 'x' which is declared here on type 'Attribs1'
5252
<test1 var="10" />; // Error, no 'var' property
53-
~~~~~~~~
53+
~~~
5454
!!! error TS2322: Type '{ var: string; }' is not assignable to type 'Attribs1'.
5555
!!! error TS2322: Property 'var' does not exist on type 'Attribs1'.
5656

tests/baselines/reference/tsxAttributeResolution11.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ tests/cases/conformance/jsx/file.tsx(11,22): error TS2322: Type '{ bar: string;
2727

2828
// Should be an OK
2929
var x = <MyComponent bar='world' />;
30-
~~~~~~~~~~~
30+
~~~
3131
!!! error TS2322: Type '{ bar: string; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'.
3232
!!! error TS2322: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'.
3333

tests/baselines/reference/tsxAttributeResolution15.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ tests/cases/conformance/jsx/file.tsx(14,44): error TS7017: Element implicitly ha
1515

1616
// Error
1717
let a = <BigGreeter prop1="hello" />
18-
~~~~~~~~~~~~~
18+
~~~~~
1919
!!! error TS2322: Type '{ prop1: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<BigGreeter> & { children?: ReactNode; }'.
2020
!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<BigGreeter> & { children?: ReactNode; }'.
2121

tests/baselines/reference/tsxElementResolution11.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ tests/cases/conformance/jsx/file.tsx(17,7): error TS2322: Type '{ x: number; }'
2020
}
2121
var Obj2: Obj2type;
2222
<Obj2 x={10} />; // Error
23-
~~~~~~
23+
~
2424
!!! error TS2322: Type '{ x: number; }' is not assignable to type '{ q?: number; }'.
2525
!!! error TS2322: Property 'x' does not exist on type '{ q?: number; }'.
2626

tests/baselines/reference/tsxElementResolution3.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ tests/cases/conformance/jsx/file.tsx(12,7): error TS2322: Type '{ w: string; }'
1515

1616
// Error
1717
<span w='err' />;
18-
~~~~~~~
18+
~
1919
!!! error TS2322: Type '{ w: string; }' is not assignable to type '{ n: string; }'.
2020
!!! error TS2322: Property 'w' does not exist on type '{ n: string; }'.

tests/baselines/reference/tsxElementResolution4.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ tests/cases/conformance/jsx/file.tsx(16,7): error TS2322: Type '{ q: string; }'
1919

2020
// Error
2121
<span q='' />;
22-
~~~~
22+
~
2323
!!! error TS2322: Type '{ q: string; }' is not assignable to type '{ m: string; }'.
2424
!!! error TS2322: Property 'q' does not exist on type '{ m: string; }'.
2525

tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232
8282
!!! error TS2322: Type '{ foo: number; }' is missing the following properties from type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: string; }': bar, baz
8383
const c = <Component bar="yes" baz="yeah" />;
8484
const d = <Component bar="yes" baz="yo" bat="ohno" />; // Error, baz not a valid prop
85-
~~~~~~~~~~
85+
~~~
8686
!!! error TS2322: Type '{ bar: string; baz: string; bat: string; }' is not assignable to type 'Defaultize<InferredPropTypes<{ foo: PropTypeChecker<number, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<string, true>; }>, { foo: number; }>'.
8787
!!! error TS2322: Property 'bat' does not exist on type 'Defaultize<InferredPropTypes<{ foo: PropTypeChecker<number, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<string, true>; }>, { foo: number; }>'.
8888
const e = <Component foo={12} bar={null} baz="cool" />; // bar is nullable/undefinable since it's not marked `isRequired`
@@ -116,7 +116,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232
116116

117117
const k = <JustDefaultProps foo={12} />;
118118
const l = <JustDefaultProps foo={12} bar="ok" />; // error, no prop named bar
119-
~~~~~~~~
119+
~~~
120120
!!! error TS2322: Type '{ foo: number; bar: string; }' is not assignable to type 'Defaultize<{}, { foo: number; }>'.
121121
!!! error TS2322: Property 'bar' does not exist on type 'Defaultize<{}, { foo: number; }>'.
122122
const m = <JustDefaultProps foo="no" />; // error, wrong type
@@ -145,7 +145,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232
145145
!!! error TS2322: Type '{ foo: string; }' is missing the following properties from type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: number; }': bar, baz
146146
const p = <BothWithSpecifiedGeneric bar="yes" baz={12} />;
147147
const q = <BothWithSpecifiedGeneric bar="yes" baz={12} bat="ohno" />; // Error, baz not a valid prop
148-
~~~~~~~~~~
148+
~~~
149149
!!! error TS2322: Type '{ bar: string; baz: number; bat: string; }' is not assignable to type 'Defaultize<FooProps & InferredPropTypes<{ foo: PropTypeChecker<string, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<number, true>; }>, { foo: string; }>'.
150150
!!! error TS2322: Property 'bat' does not exist on type 'Defaultize<FooProps & InferredPropTypes<{ foo: PropTypeChecker<string, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<number, true>; }>, { foo: string; }>'.
151151
const r = <BothWithSpecifiedGeneric foo="no" bar={null} baz={0} />; // bar is nullable/undefinable since it's not marked `isRequired`
@@ -181,7 +181,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232
181181

182182
const x = <JustDefaultPropsWithSpecifiedGeneric foo="eh" />;
183183
const y = <JustDefaultPropsWithSpecifiedGeneric foo="no" bar="ok" />; // error, no prop named bar
184-
~~~~~~~~
184+
~~~
185185
!!! error TS2322: Type '{ foo: string; bar: string; }' is not assignable to type 'Defaultize<FooProps, { foo: string; }>'.
186186
!!! error TS2322: Property 'bar' does not exist on type 'Defaultize<FooProps, { foo: string; }>'.
187187
const z = <JustDefaultPropsWithSpecifiedGeneric foo={12} />; // error, wrong type

tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,6 @@ tests/cases/conformance/jsx/file.tsx(24,40): error TS2322: Type '{ X: string; x:
4848
!!! error TS2322: Types of property 'x' are incompatible.
4949
!!! error TS2322: Type 'number' is not assignable to type 'string'.
5050
let w1 = <Poisoned {...{x: 5, y: "2"}} X="hi" />;
51-
~~~~~~
51+
~
5252
!!! error TS2322: Type '{ X: string; x: number; y: "2"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Poisoned> & PoisonedProp & { children?: ReactNode; }'.
5353
!!! error TS2322: Property 'X' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Poisoned> & PoisonedProp & { children?: ReactNode; }'.

tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ tests/cases/conformance/jsx/file.tsx(36,12): error TS2769: No overload matches t
117117
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:43: The expected type comes from property 'yy1' which is declared here on type 'IntrinsicAttributes & { yy: number; yy1: string; }'
118118
const c3 = <OneThing {...obj} {...{extra: "extra attr"}} />; // This is OK becuase all attribute are spread
119119
const c4 = <OneThing {...obj} y1={10000} />; // extra property;
120-
~~~~~~~~~~
120+
~~
121121
!!! error TS2769: No overload matches this call.
122122
!!! error TS2769: Overload 1 of 2, '(): Element', gave the following error.
123123
!!! error TS2769: Type '{ y1: number; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes'.

0 commit comments

Comments
 (0)