report extraneous jsx attribute error on attribute name instead of entire attribute assignment

This commit is contained in:
Nathan Fenner
2019-09-18 16:31:44 -07:00
parent 940231785e
commit dbc17229f7
12 changed files with 22 additions and 27 deletions
+4 -9
View File
@@ -13040,15 +13040,10 @@ namespace ts {
// JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal.
// However, using an object-literal error message will be very confusing to the users so we give different a message.
// TODO: Spelling suggestions for excess jsx attributes (needs new diagnostic messages)
if (errorNode && isJsxOpeningLikeElement(errorNode.parent)) {
const attributes = errorNode.parent.attributes;
for (const jsxProperty of attributes.properties) {
if (jsxProperty.kind === SyntaxKind.JsxAttribute && jsxProperty.name.escapedText === prop.escapedName) {
// Move the error node to the actual JSX property, instead of pointing to the identifier in the JSX element.
errorNode = jsxProperty;
}
}
if (prop.valueDeclaration && isNamedDeclaration(prop.valueDeclaration) && prop.valueDeclaration.name && prop.valueDeclaration.name.pos !== -1) {
// If the "children" attribute is extraneous `<NoChild>extra</NoChild>` then the declaration's name has no location.
// In that case, do not update the error location, since there's no name to point to.
errorNode = prop.valueDeclaration.name;
}
reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(errorTarget));
}
@@ -38,11 +38,11 @@ tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type 'number' is not a
!!! error TS2322: Type 'string' is not assignable to type 'number'.
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:10:2: The expected type comes from property 'x' which is declared here on type 'Attribs1'
<test1 y={0} />; // Error, no property "y"
~~~~~
~
!!! error TS2322: Type '{ y: number; }' is not assignable to type 'Attribs1'.
!!! error TS2322: Property 'y' does not exist on type 'Attribs1'.
<test1 y="foo" />; // Error, no property "y"
~~~~~~~
~
!!! error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'.
!!! error TS2322: Property 'y' does not exist on type 'Attribs1'.
<test1 x="32" />; // Error, "32" is not number
@@ -50,7 +50,7 @@ tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type 'number' is not a
!!! error TS2322: Type 'string' is not assignable to type 'number'.
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:10:2: The expected type comes from property 'x' which is declared here on type 'Attribs1'
<test1 var="10" />; // Error, no 'var' property
~~~~~~~~
~~~
!!! error TS2322: Type '{ var: string; }' is not assignable to type 'Attribs1'.
!!! error TS2322: Property 'var' does not exist on type 'Attribs1'.
@@ -27,7 +27,7 @@ tests/cases/conformance/jsx/file.tsx(11,22): error TS2322: Type '{ bar: string;
// Should be an OK
var x = <MyComponent bar='world' />;
~~~~~~~~~~~
~~~
!!! error TS2322: Type '{ bar: string; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'.
!!! error TS2322: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'.
@@ -15,7 +15,7 @@ tests/cases/conformance/jsx/file.tsx(14,44): error TS7017: Element implicitly ha
// Error
let a = <BigGreeter prop1="hello" />
~~~~~~~~~~~~~
~~~~~
!!! error TS2322: Type '{ prop1: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<BigGreeter> & { children?: ReactNode; }'.
!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<BigGreeter> & { children?: ReactNode; }'.
@@ -20,7 +20,7 @@ tests/cases/conformance/jsx/file.tsx(17,7): error TS2322: Type '{ x: number; }'
}
var Obj2: Obj2type;
<Obj2 x={10} />; // Error
~~~~~~
~
!!! error TS2322: Type '{ x: number; }' is not assignable to type '{ q?: number; }'.
!!! error TS2322: Property 'x' does not exist on type '{ q?: number; }'.
@@ -15,6 +15,6 @@ tests/cases/conformance/jsx/file.tsx(12,7): error TS2322: Type '{ w: string; }'
// Error
<span w='err' />;
~~~~~~~
~
!!! error TS2322: Type '{ w: string; }' is not assignable to type '{ n: string; }'.
!!! error TS2322: Property 'w' does not exist on type '{ n: string; }'.
@@ -19,7 +19,7 @@ tests/cases/conformance/jsx/file.tsx(16,7): error TS2322: Type '{ q: string; }'
// Error
<span q='' />;
~~~~
~
!!! error TS2322: Type '{ q: string; }' is not assignable to type '{ m: string; }'.
!!! error TS2322: Property 'q' does not exist on type '{ m: string; }'.
@@ -82,7 +82,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232
!!! error TS2322: Type '{ foo: number; }' is missing the following properties from type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: string; }': bar, baz
const c = <Component bar="yes" baz="yeah" />;
const d = <Component bar="yes" baz="yo" bat="ohno" />; // Error, baz not a valid prop
~~~~~~~~~~
~~~
!!! 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; }>'.
!!! 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; }>'.
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
const k = <JustDefaultProps foo={12} />;
const l = <JustDefaultProps foo={12} bar="ok" />; // error, no prop named bar
~~~~~~~~
~~~
!!! error TS2322: Type '{ foo: number; bar: string; }' is not assignable to type 'Defaultize<{}, { foo: number; }>'.
!!! error TS2322: Property 'bar' does not exist on type 'Defaultize<{}, { foo: number; }>'.
const m = <JustDefaultProps foo="no" />; // error, wrong type
@@ -145,7 +145,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232
!!! error TS2322: Type '{ foo: string; }' is missing the following properties from type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: number; }': bar, baz
const p = <BothWithSpecifiedGeneric bar="yes" baz={12} />;
const q = <BothWithSpecifiedGeneric bar="yes" baz={12} bat="ohno" />; // Error, baz not a valid prop
~~~~~~~~~~
~~~
!!! 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; }>'.
!!! 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; }>'.
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
const x = <JustDefaultPropsWithSpecifiedGeneric foo="eh" />;
const y = <JustDefaultPropsWithSpecifiedGeneric foo="no" bar="ok" />; // error, no prop named bar
~~~~~~~~
~~~
!!! error TS2322: Type '{ foo: string; bar: string; }' is not assignable to type 'Defaultize<FooProps, { foo: string; }>'.
!!! error TS2322: Property 'bar' does not exist on type 'Defaultize<FooProps, { foo: string; }>'.
const z = <JustDefaultPropsWithSpecifiedGeneric foo={12} />; // error, wrong type
@@ -48,6 +48,6 @@ tests/cases/conformance/jsx/file.tsx(24,40): error TS2322: Type '{ X: string; x:
!!! error TS2322: Types of property 'x' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
let w1 = <Poisoned {...{x: 5, y: "2"}} X="hi" />;
~~~~~~
~
!!! error TS2322: Type '{ X: string; x: number; y: "2"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Poisoned> & PoisonedProp & { children?: ReactNode; }'.
!!! error TS2322: Property 'X' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Poisoned> & PoisonedProp & { children?: ReactNode; }'.
@@ -117,7 +117,7 @@ tests/cases/conformance/jsx/file.tsx(36,12): error TS2769: No overload matches t
!!! 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; }'
const c3 = <OneThing {...obj} {...{extra: "extra attr"}} />; // This is OK becuase all attribute are spread
const c4 = <OneThing {...obj} y1={10000} />; // extra property;
~~~~~~~~~~
~~
!!! error TS2769: No overload matches this call.
!!! error TS2769: Overload 1 of 2, '(): Element', gave the following error.
!!! error TS2769: Type '{ y1: number; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes'.
@@ -32,7 +32,7 @@ tests/cases/conformance/jsx/file.tsx(45,11): error TS2559: Type '{ prop1: boolea
let a1 = <Greet name='world' extra-prop />;
// Error
let b = <Greet naaame='world' />;
~~~~~~~~~~~~~~
~~~~~~
!!! error TS2322: Type '{ naaame: string; }' is not assignable to type 'IntrinsicAttributes & { name: string; }'.
!!! error TS2322: Property 'naaame' does not exist on type 'IntrinsicAttributes & { name: string; }'.
@@ -47,7 +47,7 @@ tests/cases/conformance/jsx/file.tsx(45,11): error TS2559: Type '{ prop1: boolea
!!! error TS2322: Type 'number' is not assignable to type 'string'.
// Error
let f = <Meet naaaaaaame='no' />;
~~~~~~~~~~~~~~~
~~~~~~~~~~
!!! error TS2322: Type '{ naaaaaaame: string; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'.
!!! error TS2322: Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'.
@@ -65,7 +65,7 @@ tests/cases/conformance/jsx/file.tsx(45,11): error TS2559: Type '{ prop1: boolea
!!! error TS2322: Type '{ prop1: true; }' is not assignable to type 'IntrinsicAttributes'.
!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes'.
let i1 = <EmptyPropSFC ref={x => x.greeting.substr(10)} />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~
!!! error TS2322: Type '{ ref: (x: any) => any; }' is not assignable to type 'IntrinsicAttributes'.
!!! error TS2322: Property 'ref' does not exist on type 'IntrinsicAttributes'.
@@ -25,7 +25,7 @@ tests/cases/conformance/jsx/file.tsx(35,26): error TS2339: Property 'propertyNot
let b = <Greet key="k" />;
// Error - not allowed to specify 'ref' on SFCs
let c = <Greet ref="myRef" />;
~~~~~~~~~~~
~~~
!!! error TS2322: Type '{ ref: string; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'.
!!! error TS2322: Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'.