Skip to content

Commit d89d68f

Browse files
authored
make jsx attributes mutable locations (microsoft#20710)
1 parent d619238 commit d89d68f

35 files changed

Lines changed: 274 additions & 270 deletions

src/compiler/checker.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14802,6 +14802,12 @@ namespace ts {
1480214802
}
1480314803
}
1480414804

14805+
function checkJsxAttribute(node: JsxAttribute, checkMode?: CheckMode) {
14806+
return node.initializer
14807+
? checkExpressionForMutableLocation(node.initializer, checkMode)
14808+
: trueType; // <Elem attr /> is sugar for <Elem attr={true} />
14809+
}
14810+
1480514811
/**
1480614812
* Get attributes type of the JSX opening-like element. The result is from resolving "attributes" property of the opening-like element.
1480714813
*
@@ -14824,9 +14830,7 @@ namespace ts {
1482414830
for (const attributeDecl of attributes.properties) {
1482514831
const member = attributeDecl.symbol;
1482614832
if (isJsxAttribute(attributeDecl)) {
14827-
const exprType = attributeDecl.initializer ?
14828-
checkExpression(attributeDecl.initializer, checkMode) :
14829-
trueType; // <Elem attr /> is sugar for <Elem attr={true} />
14833+
const exprType = checkJsxAttribute(attributeDecl, checkMode);
1483014834

1483114835
const attributeSymbol = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.escapedName);
1483214836
attributeSymbol.declarations = member.declarations;

tests/baselines/reference/checkJsxChildrenProperty14.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
tests/cases/conformance/jsx/file.tsx(42,27): error TS2322: Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
2-
Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'SingleChildProp'.
1+
tests/cases/conformance/jsx/file.tsx(42,27): error TS2322: Type '{ a: number; b: string; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
2+
Type '{ a: number; b: string; children: Element[]; }' is not assignable to type 'SingleChildProp'.
33
Types of property 'children' are incompatible.
44
Type 'Element[]' is not assignable to type 'Element'.
55
Property 'type' is missing in type 'Element[]'.
@@ -49,8 +49,8 @@ tests/cases/conformance/jsx/file.tsx(42,27): error TS2322: Type '{ a: 10; b: "hi
4949
// Error
5050
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
5151
~~~~~~~~~~~~~
52-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
53-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'SingleChildProp'.
52+
!!! error TS2322: Type '{ a: number; b: string; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
53+
!!! error TS2322: Type '{ a: number; b: string; children: Element[]; }' is not assignable to type 'SingleChildProp'.
5454
!!! error TS2322: Types of property 'children' are incompatible.
5555
!!! error TS2322: Type 'Element[]' is not assignable to type 'Element'.
5656
!!! error TS2322: Property 'type' is missing in type 'Element[]'.

tests/baselines/reference/checkJsxChildrenProperty2.errors.txt

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
tests/cases/conformance/jsx/file.tsx(14,15): error TS2322: Type '{ a: 10; b: "hi"; }' is not assignable to type 'IntrinsicAttributes & Prop'.
2-
Type '{ a: 10; b: "hi"; }' is not assignable to type 'Prop'.
3-
Property 'children' is missing in type '{ a: 10; b: "hi"; }'.
1+
tests/cases/conformance/jsx/file.tsx(14,15): error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
2+
Type '{ a: number; b: string; }' is not assignable to type 'Prop'.
3+
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 '{ a: 10; b: "hi"; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
6-
Type '{ a: 10; b: "hi"; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'Prop'.
5+
tests/cases/conformance/jsx/file.tsx(31,11): error TS2322: Type '{ a: number; b: string; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
6+
Type '{ a: number; b: string; children: (Element | ((name: string) => Element))[]; }' 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 '{ a: 10; b: "hi"; children: (Element | 1000000)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
12-
Type '{ a: 10; b: "hi"; children: (Element | 1000000)[]; }' is not assignable to type 'Prop'.
11+
tests/cases/conformance/jsx/file.tsx(37,11): error TS2322: Type '{ a: number; b: string; children: (Element | 1000000)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
12+
Type '{ a: number; b: string; children: (Element | 1000000)[]; }' is not assignable to type 'Prop'.
1313
Types of property 'children' are incompatible.
1414
Type '(Element | 1000000)[]' is not assignable to type 'string | Element'.
1515
Type '(Element | 1000000)[]' is not assignable to type 'Element'.
1616
Property 'type' is missing in type '(Element | 1000000)[]'.
17-
tests/cases/conformance/jsx/file.tsx(43,11): error TS2322: Type '{ a: 10; b: "hi"; children: (string | Element)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
18-
Type '{ a: 10; b: "hi"; children: (string | Element)[]; }' is not assignable to type 'Prop'.
17+
tests/cases/conformance/jsx/file.tsx(43,11): error TS2322: Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
18+
Type '{ a: number; b: string; children: (string | Element)[]; }' 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 '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
24-
Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'Prop'.
23+
tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: number; b: string; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
24+
Type '{ a: number; b: string; children: Element[]; }' is not assignable to type 'Prop'.
2525
Types of property 'children' are incompatible.
2626
Type 'Element[]' is not assignable to type 'string | Element'.
2727
Type 'Element[]' is not assignable to type 'Element'.
@@ -44,9 +44,9 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: 10; b: "hi
4444
// Error: missing children
4545
let k = <Comp a={10} b="hi" />;
4646
~~~~~~~~~~~~~
47-
!!! error TS2322: Type '{ a: 10; b: "hi"; }' is not assignable to type 'IntrinsicAttributes & Prop'.
48-
!!! error TS2322: Type '{ a: 10; b: "hi"; }' is not assignable to type 'Prop'.
49-
!!! error TS2322: Property 'children' is missing in type '{ a: 10; b: "hi"; }'.
47+
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
48+
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'Prop'.
49+
!!! error TS2322: Property 'children' is missing in type '{ a: number; b: string; }'.
5050

5151
let k0 =
5252
<Comp a={10} b="hi" children="Random" >
@@ -67,8 +67,8 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: 10; b: "hi
6767
let k2 =
6868
<Comp a={10} b="hi">
6969
~~~~~~~~~~~~~
70-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
71-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'Prop'.
70+
!!! error TS2322: Type '{ a: number; b: string; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
71+
!!! error TS2322: Type '{ a: number; b: string; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'Prop'.
7272
!!! error TS2322: Types of property 'children' are incompatible.
7373
!!! error TS2322: Type '(Element | ((name: string) => Element))[]' is not assignable to type 'string | Element'.
7474
!!! error TS2322: Type '(Element | ((name: string) => Element))[]' is not assignable to type 'Element'.
@@ -80,8 +80,8 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: 10; b: "hi
8080
let k3 =
8181
<Comp a={10} b="hi">
8282
~~~~~~~~~~~~~
83-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: (Element | 1000000)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
84-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: (Element | 1000000)[]; }' is not assignable to type 'Prop'.
83+
!!! error TS2322: Type '{ a: number; b: string; children: (Element | 1000000)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
84+
!!! error TS2322: Type '{ a: number; b: string; children: (Element | 1000000)[]; }' is not assignable to type 'Prop'.
8585
!!! error TS2322: Types of property 'children' are incompatible.
8686
!!! error TS2322: Type '(Element | 1000000)[]' is not assignable to type 'string | Element'.
8787
!!! error TS2322: Type '(Element | 1000000)[]' is not assignable to type 'Element'.
@@ -93,8 +93,8 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: 10; b: "hi
9393
let k4 =
9494
<Comp a={10} b="hi" >
9595
~~~~~~~~~~~~~
96-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: (string | Element)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
97-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: (string | Element)[]; }' is not assignable to type 'Prop'.
96+
!!! error TS2322: Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
97+
!!! error TS2322: Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'Prop'.
9898
!!! error TS2322: Types of property 'children' are incompatible.
9999
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'string | Element'.
100100
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element'.
@@ -106,8 +106,8 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: 10; b: "hi
106106
let k5 =
107107
<Comp a={10} b="hi" >
108108
~~~~~~~~~~~~~
109-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
110-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'Prop'.
109+
!!! error TS2322: Type '{ a: number; b: string; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
110+
!!! error TS2322: Type '{ a: number; b: string; children: Element[]; }' is not assignable to type 'Prop'.
111111
!!! error TS2322: Types of property 'children' are incompatible.
112112
!!! error TS2322: Type 'Element[]' is not assignable to type 'string | Element'.
113113
!!! error TS2322: Type 'Element[]' is not assignable to type 'Element'.

tests/baselines/reference/checkJsxChildrenProperty5.errors.txt

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
tests/cases/conformance/jsx/file.tsx(20,15): error TS2322: Type '{ a: 10; b: "hi"; }' is not assignable to type 'IntrinsicAttributes & Prop'.
2-
Type '{ a: 10; b: "hi"; }' is not assignable to type 'Prop'.
3-
Property 'children' is missing in type '{ a: 10; b: "hi"; }'.
4-
tests/cases/conformance/jsx/file.tsx(24,11): error TS2322: Type '{ a: 10; b: "hi"; children: Element; }' is not assignable to type 'IntrinsicAttributes & Prop'.
5-
Type '{ a: 10; b: "hi"; children: Element; }' is not assignable to type 'Prop'.
1+
tests/cases/conformance/jsx/file.tsx(20,15): error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
2+
Type '{ a: number; b: string; }' is not assignable to type 'Prop'.
3+
Property 'children' is missing in type '{ a: number; b: string; }'.
4+
tests/cases/conformance/jsx/file.tsx(24,11): error TS2322: Type '{ a: number; b: string; children: Element; }' is not assignable to type 'IntrinsicAttributes & Prop'.
5+
Type '{ a: number; b: string; children: Element; }' 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 '{ a: 10; b: "hi"; children: typeof Button; }' is not assignable to type 'IntrinsicAttributes & Prop'.
10-
Type '{ a: 10; b: "hi"; children: typeof Button; }' is not assignable to type 'Prop'.
9+
tests/cases/conformance/jsx/file.tsx(28,11): error TS2322: Type '{ a: number; b: string; children: typeof Button; }' is not assignable to type 'IntrinsicAttributes & Prop'.
10+
Type '{ a: number; b: string; children: typeof Button; }' is not assignable to type 'Prop'.
1111
Types of property 'children' are incompatible.
1212
Type 'typeof Button' is not assignable to type 'Button'.
1313
Property 'render' is missing in type 'typeof Button'.
@@ -35,16 +35,16 @@ tests/cases/conformance/jsx/file.tsx(28,11): error TS2322: Type '{ a: 10; b: "hi
3535
// Error: no children specified
3636
let k = <Comp a={10} b="hi" />;
3737
~~~~~~~~~~~~~
38-
!!! error TS2322: Type '{ a: 10; b: "hi"; }' is not assignable to type 'IntrinsicAttributes & Prop'.
39-
!!! error TS2322: Type '{ a: 10; b: "hi"; }' is not assignable to type 'Prop'.
40-
!!! error TS2322: Property 'children' is missing in type '{ a: 10; b: "hi"; }'.
38+
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
39+
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'Prop'.
40+
!!! 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">
4545
~~~~~~~~~~~~~
46-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: Element; }' is not assignable to type 'IntrinsicAttributes & Prop'.
47-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: Element; }' is not assignable to type 'Prop'.
46+
!!! error TS2322: Type '{ a: number; b: string; children: Element; }' is not assignable to type 'IntrinsicAttributes & Prop'.
47+
!!! error TS2322: Type '{ a: number; b: string; children: Element; }' is not assignable to type 'Prop'.
4848
!!! error TS2322: Types of property 'children' are incompatible.
4949
!!! error TS2322: Type 'Element' is not assignable to type 'Button'.
5050
!!! error TS2322: Property 'render' is missing in type 'Element'.
@@ -53,8 +53,8 @@ tests/cases/conformance/jsx/file.tsx(28,11): error TS2322: Type '{ a: 10; b: "hi
5353
let k2 =
5454
<Comp a={10} b="hi">
5555
~~~~~~~~~~~~~
56-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: typeof Button; }' is not assignable to type 'IntrinsicAttributes & Prop'.
57-
!!! error TS2322: Type '{ a: 10; b: "hi"; children: typeof Button; }' is not assignable to type 'Prop'.
56+
!!! error TS2322: Type '{ a: number; b: string; children: typeof Button; }' is not assignable to type 'IntrinsicAttributes & Prop'.
57+
!!! error TS2322: Type '{ a: number; b: string; children: typeof Button; }' is not assignable to type 'Prop'.
5858
!!! error TS2322: Types of property 'children' are incompatible.
5959
!!! error TS2322: Type 'typeof Button' is not assignable to type 'Button'.
6060
!!! error TS2322: Property 'render' is missing in type 'typeof Button'.

0 commit comments

Comments
 (0)