Skip to content

Commit ae73a91

Browse files
authored
Allow JSXAttributes types to be shortcut-spread into the spread type like normal objects (microsoft#19047)
* Bring jsx type resolution inline with normal objects, move jsx attribute property ignorign into relationship check * Improved errors and reordered members * Always use inferrential mode for jsx pass * Add some missing skipLibChecks * New check mode instead of odd type mapper * Do not enable object literal freshness checks on jsx spreads * Fix minor style nits * Update order of type for test * Accept corrected baseline
1 parent dd933f4 commit ae73a91

17 files changed

Lines changed: 315 additions & 144 deletions

src/compiler/checker.ts

Lines changed: 56 additions & 54 deletions
Large diffs are not rendered by default.

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: 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'.
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'.
2+
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'.
55
Property 'type' is missing in type 'Element[]'.
@@ -49,8 +49,8 @@ tests/cases/conformance/jsx/file.tsx(42,27): error TS2322: Type '{ a: number; b:
4949
// Error
5050
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
5151
~~~~~~~~~~~~~
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'.
52+
!!! error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
53+
!!! error TS2322: Type '{ children: Element[]; a: number; b: string; }' 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: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,26 @@ tests/cases/conformance/jsx/file.tsx(14,15): error TS2322: Type '{ a: number; b:
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 '{ 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'.
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'.
6+
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 '{ 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'.
11+
tests/cases/conformance/jsx/file.tsx(37,11): error TS2322: Type '{ children: (Element | 1000000)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
12+
Type '{ children: (Element | 1000000)[]; a: number; b: string; }' 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: 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'.
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'.
18+
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 '{ 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'.
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'.
24+
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'.
2727
Type 'Element[]' is not assignable to type 'Element'.
@@ -67,8 +67,8 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: number; b:
6767
let k2 =
6868
<Comp a={10} b="hi">
6969
~~~~~~~~~~~~~
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'.
70+
!!! error TS2322: Type '{ children: (Element | ((name: string) => Element))[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
71+
!!! 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.
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: number; b:
8080
let k3 =
8181
<Comp a={10} b="hi">
8282
~~~~~~~~~~~~~
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'.
83+
!!! error TS2322: Type '{ children: (Element | 1000000)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
84+
!!! error TS2322: Type '{ children: (Element | 1000000)[]; a: number; b: string; }' 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: number; b:
9393
let k4 =
9494
<Comp a={10} b="hi" >
9595
~~~~~~~~~~~~~
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'.
96+
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
97+
!!! 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.
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: number; b:
106106
let k5 =
107107
<Comp a={10} b="hi" >
108108
~~~~~~~~~~~~~
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'.
109+
!!! error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
110+
!!! error TS2322: Type '{ children: Element[]; a: number; b: string; }' 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: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
tests/cases/conformance/jsx/file.tsx(20,15): 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 '{ 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'.
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'.
5+
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 '{ 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'.
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'.
10+
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'.
1313
Property 'render' is missing in type 'typeof Button'.
@@ -43,8 +43,8 @@ tests/cases/conformance/jsx/file.tsx(28,11): error TS2322: Type '{ a: number; b:
4343
let k1 =
4444
<Comp a={10} b="hi">
4545
~~~~~~~~~~~~~
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'.
46+
!!! error TS2322: Type '{ children: Element; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
47+
!!! error TS2322: Type '{ children: Element; a: number; b: string; }' 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: number; b:
5353
let k2 =
5454
<Comp a={10} b="hi">
5555
~~~~~~~~~~~~~
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'.
56+
!!! error TS2322: Type '{ children: typeof Button; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
57+
!!! 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.
5959
!!! error TS2322: Type 'typeof Button' is not assignable to type 'Button'.
6060
!!! error TS2322: Property 'render' is missing in type 'typeof Button'.

tests/baselines/reference/checkJsxChildrenProperty7.errors.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
tests/cases/conformance/jsx/file.tsx(24,16): error TS2322: Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
2-
Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'Prop'.
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'.
2+
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 '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
9-
Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'Prop'.
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'.
9+
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 '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
14-
Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'Prop'.
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'.
14+
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[]'.
1717
Type '(string | Element)[]' is not assignable to type 'Element[]'.
@@ -43,25 +43,25 @@ tests/cases/conformance/jsx/file.tsx(27,16): error TS2322: Type '{ a: number; b:
4343
// Error: whitespaces matters
4444
let k1 = <Comp a={10} b="hi"><Button /> <AnotherButton /></Comp>;
4545
~~~~~~~~~~~~~
46-
!!! error TS2322: Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
47-
!!! error TS2322: Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'Prop'.
46+
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
47+
!!! 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.
4949
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
5050
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element[]'.
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 />
5454
~~~~~~~~~~~~~
55-
!!! error TS2322: Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
56-
!!! error TS2322: Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'Prop'.
55+
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
56+
!!! 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 />
6262
~~~~~~~~~~~~~
63-
!!! error TS2322: Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'IntrinsicAttributes & Prop'.
64-
!!! error TS2322: Type '{ a: number; b: string; children: (string | Element)[]; }' is not assignable to type 'Prop'.
63+
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & Prop'.
64+
!!! 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.
6666
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
6767
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element[]'.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//// [jsxSpreadFirstUnionNoErrors.tsx]
2+
import React from "react";
3+
4+
type InfoProps =
5+
| { status: "hidden" }
6+
| { status: "visible"; content: string };
7+
8+
const Info = (props: InfoProps) =>
9+
props.status === "hidden"
10+
? <noscript />
11+
: <div>{props.content}</div>;
12+
13+
const a = <Info status="hidden" />;
14+
const b = <Info status="visible" content="hello world" />;
15+
declare const infoProps: InfoProps;
16+
17+
const c = <Info {...infoProps} />;
18+
19+
//// [jsxSpreadFirstUnionNoErrors.js]
20+
"use strict";
21+
var __assign = (this && this.__assign) || Object.assign || function(t) {
22+
for (var s, i = 1, n = arguments.length; i < n; i++) {
23+
s = arguments[i];
24+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
25+
t[p] = s[p];
26+
}
27+
return t;
28+
};
29+
exports.__esModule = true;
30+
var react_1 = require("react");
31+
var Info = function (props) {
32+
return props.status === "hidden"
33+
? react_1["default"].createElement("noscript", null)
34+
: react_1["default"].createElement("div", null, props.content);
35+
};
36+
var a = react_1["default"].createElement(Info, { status: "hidden" });
37+
var b = react_1["default"].createElement(Info, { status: "visible", content: "hello world" });
38+
var c = react_1["default"].createElement(Info, __assign({}, infoProps));

0 commit comments

Comments
 (0)