Skip to content

Commit f7f5007

Browse files
authored
Fix 10625: JSX Not validating when index signature is present (microsoft#10352)
* Check for type of property declaration before using index signature * Add tests and baselines * fix linting error
1 parent 80c04f8 commit f7f5007

File tree

4 files changed

+120
-4
lines changed

4 files changed

+120
-4
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10140,10 +10140,9 @@ namespace ts {
1014010140
const correspondingPropSymbol = getPropertyOfType(elementAttributesType, node.name.text);
1014110141
correspondingPropType = correspondingPropSymbol && getTypeOfSymbol(correspondingPropSymbol);
1014210142
if (isUnhyphenatedJsxName(node.name.text)) {
10143-
// Maybe there's a string indexer?
10144-
const indexerType = getIndexTypeOfType(elementAttributesType, IndexKind.String);
10145-
if (indexerType) {
10146-
correspondingPropType = indexerType;
10143+
const attributeType = getTypeOfPropertyOfType(elementAttributesType, getTextOfPropertyName(node.name)) || getIndexTypeOfType(elementAttributesType, IndexKind.String);
10144+
if (attributeType) {
10145+
correspondingPropType = attributeType;
1014710146
}
1014810147
else {
1014910148
// If there's no corresponding property with this name, error
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
tests/cases/conformance/jsx/file.tsx(14,28): error TS2322: Type 'number' is not assignable to type 'string'.
2+
tests/cases/conformance/jsx/file.tsx(16,28): error TS2322: Type 'boolean' is not assignable to type 'string | number'.
3+
4+
5+
==== tests/cases/conformance/jsx/react.d.ts (0 errors) ====
6+
7+
declare module JSX {
8+
interface Element { }
9+
interface IntrinsicElements {
10+
div: any;
11+
}
12+
interface ElementAttributesProperty { prop: any }
13+
}
14+
15+
==== tests/cases/conformance/jsx/file.tsx (2 errors) ====
16+
17+
interface IProps {
18+
primaryText: string,
19+
[propName: string]: string | number
20+
}
21+
22+
function VerticalNavMenuItem(prop: IProps) {
23+
return <div>props.primaryText</div>
24+
}
25+
26+
function VerticalNav() {
27+
return (
28+
<div>
29+
<VerticalNavMenuItem primaryText={2} /> // error
30+
~~~~~~~~~~~~~~~
31+
!!! error TS2322: Type 'number' is not assignable to type 'string'.
32+
<VerticalNavMenuItem justRandomProp={2} primaryText={"hello"} /> // ok
33+
<VerticalNavMenuItem justRandomProp1={true} primaryText={"hello"} /> // error
34+
~~~~~~~~~~~~~~~~~~~~~~
35+
!!! error TS2322: Type 'boolean' is not assignable to type 'string | number'.
36+
</div>
37+
)
38+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//// [tests/cases/conformance/jsx/tsxAttributeResolution14.tsx] ////
2+
3+
//// [react.d.ts]
4+
5+
declare module JSX {
6+
interface Element { }
7+
interface IntrinsicElements {
8+
div: any;
9+
}
10+
interface ElementAttributesProperty { prop: any }
11+
}
12+
13+
//// [file.tsx]
14+
15+
interface IProps {
16+
primaryText: string,
17+
[propName: string]: string | number
18+
}
19+
20+
function VerticalNavMenuItem(prop: IProps) {
21+
return <div>props.primaryText</div>
22+
}
23+
24+
function VerticalNav() {
25+
return (
26+
<div>
27+
<VerticalNavMenuItem primaryText={2} /> // error
28+
<VerticalNavMenuItem justRandomProp={2} primaryText={"hello"} /> // ok
29+
<VerticalNavMenuItem justRandomProp1={true} primaryText={"hello"} /> // error
30+
</div>
31+
)
32+
}
33+
34+
//// [file.jsx]
35+
function VerticalNavMenuItem(prop) {
36+
return <div>props.primaryText</div>;
37+
}
38+
function VerticalNav() {
39+
return (<div>
40+
<VerticalNavMenuItem primaryText={2}/> // error
41+
// error
42+
<VerticalNavMenuItem justRandomProp={2} primaryText={"hello"}/> // ok
43+
// ok
44+
<VerticalNavMenuItem justRandomProp1={true} primaryText={"hello"}/> // error
45+
// error
46+
</div>);
47+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//@jsx: preserve
2+
//@module: amd
3+
4+
//@filename: react.d.ts
5+
declare module JSX {
6+
interface Element { }
7+
interface IntrinsicElements {
8+
div: any;
9+
}
10+
interface ElementAttributesProperty { prop: any }
11+
}
12+
13+
//@filename: file.tsx
14+
15+
interface IProps {
16+
primaryText: string,
17+
[propName: string]: string | number
18+
}
19+
20+
function VerticalNavMenuItem(prop: IProps) {
21+
return <div>props.primaryText</div>
22+
}
23+
24+
function VerticalNav() {
25+
return (
26+
<div>
27+
<VerticalNavMenuItem primaryText={2} /> // error
28+
<VerticalNavMenuItem justRandomProp={2} primaryText={"hello"} /> // ok
29+
<VerticalNavMenuItem justRandomProp1={true} primaryText={"hello"} /> // error
30+
</div>
31+
)
32+
}

0 commit comments

Comments
 (0)