diff --git a/tests/baselines/reference/tsxUnionElementType1.js b/tests/baselines/reference/tsxUnionElementType1.js
new file mode 100644
index 00000000000..9e4985003ee
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType1.js
@@ -0,0 +1,27 @@
+//// [file.tsx]
+
+import React = require('react');
+
+function SFC1(prop: { x: number }) {
+ return
hello
;
+};
+
+function SFC2(prop: { x: boolean }) {
+ return World
;
+}
+
+var SFCComp = SFC1 || SFC2;
+
+
+//// [file.js]
+"use strict";
+var React = require("react");
+function SFC1(prop) {
+ return React.createElement("div", null, "hello");
+}
+;
+function SFC2(prop) {
+ return React.createElement("h1", null, "World ");
+}
+var SFCComp = SFC1 || SFC2;
+React.createElement(SFCComp, { x: true });
diff --git a/tests/baselines/reference/tsxUnionElementType1.symbols b/tests/baselines/reference/tsxUnionElementType1.symbols
new file mode 100644
index 00000000000..cb743ff2735
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType1.symbols
@@ -0,0 +1,35 @@
+=== tests/cases/conformance/jsx/file.tsx ===
+
+import React = require('react');
+>React : Symbol(React, Decl(file.tsx, 0, 0))
+
+function SFC1(prop: { x: number }) {
+>SFC1 : Symbol(SFC1, Decl(file.tsx, 1, 32))
+>prop : Symbol(prop, Decl(file.tsx, 3, 14))
+>x : Symbol(x, Decl(file.tsx, 3, 21))
+
+ return hello
;
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45))
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45))
+
+};
+
+function SFC2(prop: { x: boolean }) {
+>SFC2 : Symbol(SFC2, Decl(file.tsx, 5, 2))
+>prop : Symbol(prop, Decl(file.tsx, 7, 14))
+>x : Symbol(x, Decl(file.tsx, 7, 21))
+
+ return World
;
+>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47))
+>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47))
+}
+
+var SFCComp = SFC1 || SFC2;
+>SFCComp : Symbol(SFCComp, Decl(file.tsx, 11, 3))
+>SFC1 : Symbol(SFC1, Decl(file.tsx, 1, 32))
+>SFC2 : Symbol(SFC2, Decl(file.tsx, 5, 2))
+
+
+>SFCComp : Symbol(SFCComp, Decl(file.tsx, 11, 3))
+>x : Symbol(x, Decl(file.tsx, 12, 8))
+
diff --git a/tests/baselines/reference/tsxUnionElementType1.types b/tests/baselines/reference/tsxUnionElementType1.types
new file mode 100644
index 00000000000..d89867b6f52
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType1.types
@@ -0,0 +1,39 @@
+=== tests/cases/conformance/jsx/file.tsx ===
+
+import React = require('react');
+>React : typeof React
+
+function SFC1(prop: { x: number }) {
+>SFC1 : (prop: { x: number; }) => JSX.Element
+>prop : { x: number; }
+>x : number
+
+ return hello
;
+>hello
: JSX.Element
+>div : any
+>div : any
+
+};
+
+function SFC2(prop: { x: boolean }) {
+>SFC2 : (prop: { x: boolean; }) => JSX.Element
+>prop : { x: boolean; }
+>x : boolean
+
+ return World
;
+>World
: JSX.Element
+>h1 : any
+>h1 : any
+}
+
+var SFCComp = SFC1 || SFC2;
+>SFCComp : ((prop: { x: number; }) => JSX.Element) | ((prop: { x: boolean; }) => JSX.Element)
+>SFC1 || SFC2 : ((prop: { x: number; }) => JSX.Element) | ((prop: { x: boolean; }) => JSX.Element)
+>SFC1 : (prop: { x: number; }) => JSX.Element
+>SFC2 : (prop: { x: boolean; }) => JSX.Element
+
+
+> : JSX.Element
+>SFCComp : ((prop: { x: number; }) => JSX.Element) | ((prop: { x: boolean; }) => JSX.Element)
+>x : true
+
diff --git a/tests/baselines/reference/tsxUnionElementType2.errors.txt b/tests/baselines/reference/tsxUnionElementType2.errors.txt
new file mode 100644
index 00000000000..f9f3dd3ddbb
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType2.errors.txt
@@ -0,0 +1,27 @@
+tests/cases/conformance/jsx/file.tsx(13,10): error TS2322: Type '{ x: "hi"; }' is not assignable to type '(IntrinsicAttributes & { x: number; }) | (IntrinsicAttributes & { x: boolean; })'.
+ Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'.
+ Type '{ x: "hi"; }' is not assignable to type '{ x: boolean; }'.
+ Types of property 'x' are incompatible.
+ Type '"hi"' is not assignable to type 'boolean'.
+
+
+==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
+
+ import React = require('react');
+
+ function SFC1(prop: { x: number }) {
+ return hello
;
+ };
+
+ function SFC2(prop: { x: boolean }) {
+ return World
;
+ }
+
+ var SFCComp = SFC1 || SFC2;
+
+ ~~~~~~~~
+!!! error TS2322: Type '{ x: "hi"; }' is not assignable to type '(IntrinsicAttributes & { x: number; }) | (IntrinsicAttributes & { x: boolean; })'.
+!!! error TS2322: Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'.
+!!! error TS2322: Type '{ x: "hi"; }' is not assignable to type '{ x: boolean; }'.
+!!! error TS2322: Types of property 'x' are incompatible.
+!!! error TS2322: Type '"hi"' is not assignable to type 'boolean'.
\ No newline at end of file
diff --git a/tests/baselines/reference/tsxUnionElementType2.js b/tests/baselines/reference/tsxUnionElementType2.js
new file mode 100644
index 00000000000..f8452ac7069
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType2.js
@@ -0,0 +1,27 @@
+//// [file.tsx]
+
+import React = require('react');
+
+function SFC1(prop: { x: number }) {
+ return hello
;
+};
+
+function SFC2(prop: { x: boolean }) {
+ return World
;
+}
+
+var SFCComp = SFC1 || SFC2;
+
+
+//// [file.js]
+"use strict";
+var React = require("react");
+function SFC1(prop) {
+ return React.createElement("div", null, "hello");
+}
+;
+function SFC2(prop) {
+ return React.createElement("h1", null, "World ");
+}
+var SFCComp = SFC1 || SFC2;
+React.createElement(SFCComp, { x: "hi" });
diff --git a/tests/baselines/reference/tsxUnionElementType3.js b/tests/baselines/reference/tsxUnionElementType3.js
new file mode 100644
index 00000000000..21e97e75694
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType3.js
@@ -0,0 +1,102 @@
+//// [file.tsx]
+
+import React = require('react');
+
+class RC1 extends React.Component<{x : number}, {}> {
+ render() {
+ return null;
+ }
+}
+
+class RC2 extends React.Component<{ x: string }, {}> {
+ render() {
+ return null;
+ }
+ private method() { }
+}
+
+class RC3 extends React.Component<{}, {}> {
+ render() {
+ return null;
+ }
+}
+
+class RC4 extends React.Component<{}, {}> {
+ render() {
+ return null;
+ }
+}
+
+var EmptyRCComp = RC3 || RC4;
+var PartRCComp = RC1 || RC4;
+var RCComp = RC1 || RC2;
+// OK
+let a = ;
+let a1 = ;
+let a2 = ;
+let b =
+let c =
+
+//// [file.js]
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ var extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+var React = require("react");
+var RC1 = (function (_super) {
+ __extends(RC1, _super);
+ function RC1() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ RC1.prototype.render = function () {
+ return null;
+ };
+ return RC1;
+}(React.Component));
+var RC2 = (function (_super) {
+ __extends(RC2, _super);
+ function RC2() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ RC2.prototype.render = function () {
+ return null;
+ };
+ RC2.prototype.method = function () { };
+ return RC2;
+}(React.Component));
+var RC3 = (function (_super) {
+ __extends(RC3, _super);
+ function RC3() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ RC3.prototype.render = function () {
+ return null;
+ };
+ return RC3;
+}(React.Component));
+var RC4 = (function (_super) {
+ __extends(RC4, _super);
+ function RC4() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ RC4.prototype.render = function () {
+ return null;
+ };
+ return RC4;
+}(React.Component));
+var EmptyRCComp = RC3 || RC4;
+var PartRCComp = RC1 || RC4;
+var RCComp = RC1 || RC2;
+// OK
+var a = React.createElement(RCComp, { x: "Hi" });
+var a1 = React.createElement(EmptyRCComp, null);
+var a2 = React.createElement(EmptyRCComp, { "data-prop": "hello" });
+var b = React.createElement(PartRCComp, null);
+var c = React.createElement(PartRCComp, { "data-extra": "hello" });
diff --git a/tests/baselines/reference/tsxUnionElementType3.symbols b/tests/baselines/reference/tsxUnionElementType3.symbols
new file mode 100644
index 00000000000..76f83822aa1
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType3.symbols
@@ -0,0 +1,100 @@
+=== tests/cases/conformance/jsx/file.tsx ===
+
+import React = require('react');
+>React : Symbol(React, Decl(file.tsx, 0, 0))
+
+class RC1 extends React.Component<{x : number}, {}> {
+>RC1 : Symbol(RC1, Decl(file.tsx, 1, 32))
+>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
+>React : Symbol(React, Decl(file.tsx, 0, 0))
+>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
+>x : Symbol(x, Decl(file.tsx, 3, 35))
+
+ render() {
+>render : Symbol(RC1.render, Decl(file.tsx, 3, 53))
+
+ return null;
+ }
+}
+
+class RC2 extends React.Component<{ x: string }, {}> {
+>RC2 : Symbol(RC2, Decl(file.tsx, 7, 1))
+>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
+>React : Symbol(React, Decl(file.tsx, 0, 0))
+>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
+>x : Symbol(x, Decl(file.tsx, 9, 35))
+
+ render() {
+>render : Symbol(RC2.render, Decl(file.tsx, 9, 54))
+
+ return null;
+ }
+ private method() { }
+>method : Symbol(RC2.method, Decl(file.tsx, 12, 5))
+}
+
+class RC3 extends React.Component<{}, {}> {
+>RC3 : Symbol(RC3, Decl(file.tsx, 14, 1))
+>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
+>React : Symbol(React, Decl(file.tsx, 0, 0))
+>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
+
+ render() {
+>render : Symbol(RC3.render, Decl(file.tsx, 16, 43))
+
+ return null;
+ }
+}
+
+class RC4 extends React.Component<{}, {}> {
+>RC4 : Symbol(RC4, Decl(file.tsx, 20, 1))
+>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
+>React : Symbol(React, Decl(file.tsx, 0, 0))
+>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55))
+
+ render() {
+>render : Symbol(RC4.render, Decl(file.tsx, 22, 43))
+
+ return null;
+ }
+}
+
+var EmptyRCComp = RC3 || RC4;
+>EmptyRCComp : Symbol(EmptyRCComp, Decl(file.tsx, 28, 3))
+>RC3 : Symbol(RC3, Decl(file.tsx, 14, 1))
+>RC4 : Symbol(RC4, Decl(file.tsx, 20, 1))
+
+var PartRCComp = RC1 || RC4;
+>PartRCComp : Symbol(PartRCComp, Decl(file.tsx, 29, 3))
+>RC1 : Symbol(RC1, Decl(file.tsx, 1, 32))
+>RC4 : Symbol(RC4, Decl(file.tsx, 20, 1))
+
+var RCComp = RC1 || RC2;
+>RCComp : Symbol(RCComp, Decl(file.tsx, 30, 3))
+>RC1 : Symbol(RC1, Decl(file.tsx, 1, 32))
+>RC2 : Symbol(RC2, Decl(file.tsx, 7, 1))
+
+// OK
+let a = ;
+>a : Symbol(a, Decl(file.tsx, 32, 3))
+>RCComp : Symbol(RCComp, Decl(file.tsx, 30, 3))
+>x : Symbol(x, Decl(file.tsx, 32, 15))
+
+let a1 = ;
+>a1 : Symbol(a1, Decl(file.tsx, 33, 3))
+>EmptyRCComp : Symbol(EmptyRCComp, Decl(file.tsx, 28, 3))
+
+let a2 = ;
+>a2 : Symbol(a2, Decl(file.tsx, 34, 3))
+>EmptyRCComp : Symbol(EmptyRCComp, Decl(file.tsx, 28, 3))
+>data-prop : Symbol(data-prop, Decl(file.tsx, 34, 21))
+
+let b =
+>b : Symbol(b, Decl(file.tsx, 35, 3))
+>PartRCComp : Symbol(PartRCComp, Decl(file.tsx, 29, 3))
+
+let c =
+>c : Symbol(c, Decl(file.tsx, 36, 3))
+>PartRCComp : Symbol(PartRCComp, Decl(file.tsx, 29, 3))
+>data-extra : Symbol(data-extra, Decl(file.tsx, 36, 19))
+
diff --git a/tests/baselines/reference/tsxUnionElementType3.types b/tests/baselines/reference/tsxUnionElementType3.types
new file mode 100644
index 00000000000..4753f3509b0
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType3.types
@@ -0,0 +1,112 @@
+=== tests/cases/conformance/jsx/file.tsx ===
+
+import React = require('react');
+>React : typeof React
+
+class RC1 extends React.Component<{x : number}, {}> {
+>RC1 : RC1
+>React.Component : React.Component<{ x: number; }, {}>
+>React : typeof React
+>Component : typeof React.Component
+>x : number
+
+ render() {
+>render : () => any
+
+ return null;
+>null : null
+ }
+}
+
+class RC2 extends React.Component<{ x: string }, {}> {
+>RC2 : RC2
+>React.Component : React.Component<{ x: string; }, {}>
+>React : typeof React
+>Component : typeof React.Component
+>x : string
+
+ render() {
+>render : () => any
+
+ return null;
+>null : null
+ }
+ private method() { }
+>method : () => void
+}
+
+class RC3 extends React.Component<{}, {}> {
+>RC3 : RC3
+>React.Component : React.Component<{}, {}>
+>React : typeof React
+>Component : typeof React.Component
+
+ render() {
+>render : () => any
+
+ return null;
+>null : null
+ }
+}
+
+class RC4 extends React.Component<{}, {}> {
+>RC4 : RC4
+>React.Component : React.Component<{}, {}>
+>React : typeof React
+>Component : typeof React.Component
+
+ render() {
+>render : () => any
+
+ return null;
+>null : null
+ }
+}
+
+var EmptyRCComp = RC3 || RC4;
+>EmptyRCComp : typeof RC3
+>RC3 || RC4 : typeof RC3
+>RC3 : typeof RC3
+>RC4 : typeof RC4
+
+var PartRCComp = RC1 || RC4;
+>PartRCComp : typeof RC4
+>RC1 || RC4 : typeof RC4
+>RC1 : typeof RC1
+>RC4 : typeof RC4
+
+var RCComp = RC1 || RC2;
+>RCComp : typeof RC1 | typeof RC2
+>RC1 || RC2 : typeof RC1 | typeof RC2
+>RC1 : typeof RC1
+>RC2 : typeof RC2
+
+// OK
+let a = ;
+>a : JSX.Element
+> : JSX.Element
+>RCComp : typeof RC1 | typeof RC2
+>x : string
+
+let a1 = ;
+>a1 : JSX.Element
+> : JSX.Element
+>EmptyRCComp : typeof RC3
+
+let a2 = ;
+>a2 : JSX.Element
+> : JSX.Element
+>EmptyRCComp : typeof RC3
+>data-prop : string
+
+let b =
+>b : JSX.Element
+> : JSX.Element
+>PartRCComp : typeof RC4
+
+let c =
+>c : JSX.Element
+> : JSX.Element
+>PartRCComp : typeof RC4
+>data-extra : string
+
diff --git a/tests/baselines/reference/tsxUnionElementType4.errors.txt b/tests/baselines/reference/tsxUnionElementType4.errors.txt
new file mode 100644
index 00000000000..dd2f4f2832a
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType4.errors.txt
@@ -0,0 +1,60 @@
+tests/cases/conformance/jsx/file.tsx(33,17): error TS2322: Type '{ x: true; }' is not assignable to type '(IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; }) | (IntrinsicAttributes & IntrinsicClassAttributes & { x: string; } & { children?: ReactNode; })'.
+ Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: string; } & { children?: ReactNode; }'.
+ Type '{ x: true; }' is not assignable to type '{ x: string; }'.
+ Types of property 'x' are incompatible.
+ Type 'true' is not assignable to type 'string'.
+tests/cases/conformance/jsx/file.tsx(34,21): error TS2322: Type '{ x: 10; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'.
+ Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'.
+tests/cases/conformance/jsx/file.tsx(35,22): error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'.
+ Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'.
+
+
+==== tests/cases/conformance/jsx/file.tsx (3 errors) ====
+
+ import React = require('react');
+
+ class RC1 extends React.Component<{x : number}, {}> {
+ render() {
+ return null;
+ }
+ }
+
+ class RC2 extends React.Component<{ x: string }, {}> {
+ render() {
+ return null;
+ }
+ private method() { }
+ }
+
+ class RC3 extends React.Component<{}, {}> {
+ render() {
+ return null;
+ }
+ }
+
+ class RC4 extends React.Component<{}, {}> {
+ render() {
+ return null;
+ }
+ }
+
+ var RCComp = RC1 || RC2;
+ var EmptyRCComp = RC3 || RC4;
+ var PartRCComp = RC1 || RC4;
+ // Error
+ let a = ;
+ ~
+!!! error TS2322: Type '{ x: true; }' is not assignable to type '(IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; }) | (IntrinsicAttributes & IntrinsicClassAttributes & { x: string; } & { children?: ReactNode; })'.
+!!! error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: string; } & { children?: ReactNode; }'.
+!!! error TS2322: Type '{ x: true; }' is not assignable to type '{ x: string; }'.
+!!! error TS2322: Types of property 'x' are incompatible.
+!!! error TS2322: Type 'true' is not assignable to type 'string'.
+ let b =
+ ~~~~~~
+!!! error TS2322: Type '{ x: 10; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'.
+!!! error TS2322: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'.
+ let c = ;
+ ~~~~
+!!! error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'.
+!!! error TS2322: Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & {} & { children?: ReactNode; }'.
+
\ No newline at end of file
diff --git a/tests/baselines/reference/tsxUnionElementType4.js b/tests/baselines/reference/tsxUnionElementType4.js
new file mode 100644
index 00000000000..bf49afd588b
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType4.js
@@ -0,0 +1,99 @@
+//// [file.tsx]
+
+import React = require('react');
+
+class RC1 extends React.Component<{x : number}, {}> {
+ render() {
+ return null;
+ }
+}
+
+class RC2 extends React.Component<{ x: string }, {}> {
+ render() {
+ return null;
+ }
+ private method() { }
+}
+
+class RC3 extends React.Component<{}, {}> {
+ render() {
+ return null;
+ }
+}
+
+class RC4 extends React.Component<{}, {}> {
+ render() {
+ return null;
+ }
+}
+
+var RCComp = RC1 || RC2;
+var EmptyRCComp = RC3 || RC4;
+var PartRCComp = RC1 || RC4;
+// Error
+let a = ;
+let b =
+let c = ;
+
+
+//// [file.js]
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+ var extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+var React = require("react");
+var RC1 = (function (_super) {
+ __extends(RC1, _super);
+ function RC1() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ RC1.prototype.render = function () {
+ return null;
+ };
+ return RC1;
+}(React.Component));
+var RC2 = (function (_super) {
+ __extends(RC2, _super);
+ function RC2() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ RC2.prototype.render = function () {
+ return null;
+ };
+ RC2.prototype.method = function () { };
+ return RC2;
+}(React.Component));
+var RC3 = (function (_super) {
+ __extends(RC3, _super);
+ function RC3() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ RC3.prototype.render = function () {
+ return null;
+ };
+ return RC3;
+}(React.Component));
+var RC4 = (function (_super) {
+ __extends(RC4, _super);
+ function RC4() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ RC4.prototype.render = function () {
+ return null;
+ };
+ return RC4;
+}(React.Component));
+var RCComp = RC1 || RC2;
+var EmptyRCComp = RC3 || RC4;
+var PartRCComp = RC1 || RC4;
+// Error
+var a = React.createElement(RCComp, { x: true });
+var b = React.createElement(PartRCComp, { x: 10 });
+var c = React.createElement(EmptyRCComp, { prop: true });
diff --git a/tests/baselines/reference/tsxUnionElementType5.js b/tests/baselines/reference/tsxUnionElementType5.js
new file mode 100644
index 00000000000..2d1887885bd
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType5.js
@@ -0,0 +1,40 @@
+//// [file.tsx]
+
+import React = require('react');
+
+function EmptySFC1() {
+ return hello
;
+}
+
+function EmptySFC2() {
+ return Hello
;
+}
+
+function SFC2(prop: { x: boolean }) {
+ return World
;
+}
+
+var EmptySFCComp = EmptySFC1 || EmptySFC2;
+var SFC2AndEmptyComp = SFC2 || EmptySFC1;
+
+let a =
+let a1 =
+let b =
+
+//// [file.js]
+"use strict";
+var React = require("react");
+function EmptySFC1() {
+ return React.createElement("div", null, "hello");
+}
+function EmptySFC2() {
+ return React.createElement("div", null, "Hello");
+}
+function SFC2(prop) {
+ return React.createElement("h1", null, "World");
+}
+var EmptySFCComp = EmptySFC1 || EmptySFC2;
+var SFC2AndEmptyComp = SFC2 || EmptySFC1;
+var a = React.createElement(EmptySFCComp, null);
+var a1 = React.createElement(EmptySFCComp, { "data-prop": true });
+var b = React.createElement(SFC2AndEmptyComp, { x: true });
diff --git a/tests/baselines/reference/tsxUnionElementType5.symbols b/tests/baselines/reference/tsxUnionElementType5.symbols
new file mode 100644
index 00000000000..ed1e468271d
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType5.symbols
@@ -0,0 +1,55 @@
+=== tests/cases/conformance/jsx/file.tsx ===
+
+import React = require('react');
+>React : Symbol(React, Decl(file.tsx, 0, 0))
+
+function EmptySFC1() {
+>EmptySFC1 : Symbol(EmptySFC1, Decl(file.tsx, 1, 32))
+
+ return hello
;
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45))
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45))
+}
+
+function EmptySFC2() {
+>EmptySFC2 : Symbol(EmptySFC2, Decl(file.tsx, 5, 1))
+
+ return Hello
;
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45))
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45))
+}
+
+function SFC2(prop: { x: boolean }) {
+>SFC2 : Symbol(SFC2, Decl(file.tsx, 9, 1))
+>prop : Symbol(prop, Decl(file.tsx, 11, 14))
+>x : Symbol(x, Decl(file.tsx, 11, 21))
+
+ return World
;
+>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47))
+>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47))
+}
+
+var EmptySFCComp = EmptySFC1 || EmptySFC2;
+>EmptySFCComp : Symbol(EmptySFCComp, Decl(file.tsx, 15, 3))
+>EmptySFC1 : Symbol(EmptySFC1, Decl(file.tsx, 1, 32))
+>EmptySFC2 : Symbol(EmptySFC2, Decl(file.tsx, 5, 1))
+
+var SFC2AndEmptyComp = SFC2 || EmptySFC1;
+>SFC2AndEmptyComp : Symbol(SFC2AndEmptyComp, Decl(file.tsx, 16, 3))
+>SFC2 : Symbol(SFC2, Decl(file.tsx, 9, 1))
+>EmptySFC1 : Symbol(EmptySFC1, Decl(file.tsx, 1, 32))
+
+let a =
+>a : Symbol(a, Decl(file.tsx, 18, 3))
+>EmptySFCComp : Symbol(EmptySFCComp, Decl(file.tsx, 15, 3))
+
+let a1 =
+>a1 : Symbol(a1, Decl(file.tsx, 19, 3))
+>EmptySFCComp : Symbol(EmptySFCComp, Decl(file.tsx, 15, 3))
+>data-prop : Symbol(data-prop, Decl(file.tsx, 19, 22))
+
+let b =
+>b : Symbol(b, Decl(file.tsx, 20, 3))
+>SFC2AndEmptyComp : Symbol(SFC2AndEmptyComp, Decl(file.tsx, 16, 3))
+>x : Symbol(x, Decl(file.tsx, 20, 25))
+
diff --git a/tests/baselines/reference/tsxUnionElementType5.types b/tests/baselines/reference/tsxUnionElementType5.types
new file mode 100644
index 00000000000..b2093424c44
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType5.types
@@ -0,0 +1,63 @@
+=== tests/cases/conformance/jsx/file.tsx ===
+
+import React = require('react');
+>React : typeof React
+
+function EmptySFC1() {
+>EmptySFC1 : () => JSX.Element
+
+ return hello
;
+>hello
: JSX.Element
+>div : any
+>div : any
+}
+
+function EmptySFC2() {
+>EmptySFC2 : () => JSX.Element
+
+ return Hello
;
+>Hello
: JSX.Element
+>div : any
+>div : any
+}
+
+function SFC2(prop: { x: boolean }) {
+>SFC2 : (prop: { x: boolean; }) => JSX.Element
+>prop : { x: boolean; }
+>x : boolean
+
+ return World
;
+>World
: JSX.Element
+>h1 : any
+>h1 : any
+}
+
+var EmptySFCComp = EmptySFC1 || EmptySFC2;
+>EmptySFCComp : () => JSX.Element
+>EmptySFC1 || EmptySFC2 : () => JSX.Element
+>EmptySFC1 : () => JSX.Element
+>EmptySFC2 : () => JSX.Element
+
+var SFC2AndEmptyComp = SFC2 || EmptySFC1;
+>SFC2AndEmptyComp : (prop: { x: boolean; }) => JSX.Element
+>SFC2 || EmptySFC1 : (prop: { x: boolean; }) => JSX.Element
+>SFC2 : (prop: { x: boolean; }) => JSX.Element
+>EmptySFC1 : () => JSX.Element
+
+let a =
+>a : JSX.Element
+> : JSX.Element
+>EmptySFCComp : () => JSX.Element
+
+let a1 =
+>a1 : JSX.Element
+> : JSX.Element
+>EmptySFCComp : () => JSX.Element
+>data-prop : true
+
+let b =
+>b : JSX.Element
+> : JSX.Element
+>SFC2AndEmptyComp : (prop: { x: boolean; }) => JSX.Element
+>x : true
+
diff --git a/tests/baselines/reference/tsxUnionElementType6.errors.txt b/tests/baselines/reference/tsxUnionElementType6.errors.txt
new file mode 100644
index 00000000000..7b12333bd03
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType6.errors.txt
@@ -0,0 +1,55 @@
+tests/cases/conformance/jsx/file.tsx(19,23): error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & {}'.
+ Property 'x' does not exist on type 'IntrinsicAttributes & {}'.
+tests/cases/conformance/jsx/file.tsx(20,27): error TS2322: Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'.
+ Type '{ x: "hi"; }' is not assignable to type '{ x: boolean; }'.
+ Types of property 'x' are incompatible.
+ Type '"hi"' is not assignable to type 'boolean'.
+tests/cases/conformance/jsx/file.tsx(21,9): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'.
+ Type '{}' is not assignable to type '{ x: boolean; }'.
+ Property 'x' is missing in type '{}'.
+tests/cases/conformance/jsx/file.tsx(22,27): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'.
+ Type '{}' is not assignable to type '{ x: boolean; }'.
+ Property 'x' is missing in type '{}'.
+
+
+==== tests/cases/conformance/jsx/file.tsx (4 errors) ====
+
+ import React = require('react');
+
+ function EmptySFC1() {
+ return Hi
+ }
+
+ function EmptySFC2() {
+ return Hello
+ }
+
+ function SFC2(prop: { x: boolean }) {
+ return World
;
+ }
+
+ var EmptySFCComp = EmptySFC1 || EmptySFC2;
+ var SFC2AndEmptyComp = SFC2 || EmptySFC1;
+ // Error
+ let a = ;
+ ~
+!!! error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & {}'.
+!!! error TS2322: Property 'x' does not exist on type 'IntrinsicAttributes & {}'.
+ let b = ;
+ ~~~~~~
+!!! error TS2322: Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'.
+!!! error TS2322: Type '{ x: "hi"; }' is not assignable to type '{ x: boolean; }'.
+!!! error TS2322: Types of property 'x' are incompatible.
+!!! error TS2322: Type '"hi"' is not assignable to type 'boolean'.
+ let c = ;
+ ~~~~~~~~~~~~~~~~~~~~
+!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'.
+!!! error TS2322: Type '{}' is not assignable to type '{ x: boolean; }'.
+!!! error TS2322: Property 'x' is missing in type '{}'.
+ let d = ;
+ ~~~~~~~~~
+!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'.
+!!! error TS2322: Type '{}' is not assignable to type '{ x: boolean; }'.
+!!! error TS2322: Property 'x' is missing in type '{}'.
+
+
\ No newline at end of file
diff --git a/tests/baselines/reference/tsxUnionElementType6.js b/tests/baselines/reference/tsxUnionElementType6.js
new file mode 100644
index 00000000000..96934e1e58d
--- /dev/null
+++ b/tests/baselines/reference/tsxUnionElementType6.js
@@ -0,0 +1,45 @@
+//// [file.tsx]
+
+import React = require('react');
+
+function EmptySFC1() {
+ return Hi
+}
+
+function EmptySFC2() {
+ return Hello
+}
+
+function SFC2(prop: { x: boolean }) {
+ return World
;
+}
+
+var EmptySFCComp = EmptySFC1 || EmptySFC2;
+var SFC2AndEmptyComp = SFC2 || EmptySFC1;
+// Error
+let a = ;
+let b = ;
+let c = ;
+let d = ;
+
+
+
+//// [file.js]
+"use strict";
+var React = require("react");
+function EmptySFC1() {
+ return React.createElement("div", null, "Hi");
+}
+function EmptySFC2() {
+ return React.createElement("div", null, "Hello");
+}
+function SFC2(prop) {
+ return React.createElement("h1", null, "World");
+}
+var EmptySFCComp = EmptySFC1 || EmptySFC2;
+var SFC2AndEmptyComp = SFC2 || EmptySFC1;
+// Error
+var a = React.createElement(EmptySFCComp, { x: true });
+var b = React.createElement(SFC2AndEmptyComp, { x: "hi" });
+var c = React.createElement(SFC2AndEmptyComp, null);
+var d = React.createElement(SFC2AndEmptyComp, { "data-prop": true });
diff --git a/tests/cases/conformance/jsx/tsxUnionElementType3.tsx b/tests/cases/conformance/jsx/tsxUnionElementType3.tsx
new file mode 100644
index 00000000000..5582150bf8c
--- /dev/null
+++ b/tests/cases/conformance/jsx/tsxUnionElementType3.tsx
@@ -0,0 +1,41 @@
+// @filename: file.tsx
+// @jsx: react
+// @noLib: true
+// @libFiles: react.d.ts,lib.d.ts
+
+import React = require('react');
+
+class RC1 extends React.Component<{x : number}, {}> {
+ render() {
+ return null;
+ }
+}
+
+class RC2 extends React.Component<{ x: string }, {}> {
+ render() {
+ return null;
+ }
+ private method() { }
+}
+
+class RC3 extends React.Component<{}, {}> {
+ render() {
+ return null;
+ }
+}
+
+class RC4 extends React.Component<{}, {}> {
+ render() {
+ return null;
+ }
+}
+
+var EmptyRCComp = RC3 || RC4;
+var PartRCComp = RC1 || RC4;
+var RCComp = RC1 || RC2;
+// OK
+let a = ;
+let a1 = ;
+let a2 = ;
+let b =
+let c =
\ No newline at end of file
diff --git a/tests/cases/conformance/jsx/tsxUnionElementType4.tsx b/tests/cases/conformance/jsx/tsxUnionElementType4.tsx
new file mode 100644
index 00000000000..725f93643c1
--- /dev/null
+++ b/tests/cases/conformance/jsx/tsxUnionElementType4.tsx
@@ -0,0 +1,39 @@
+// @filename: file.tsx
+// @jsx: react
+// @noLib: true
+// @libFiles: react.d.ts,lib.d.ts
+
+import React = require('react');
+
+class RC1 extends React.Component<{x : number}, {}> {
+ render() {
+ return null;
+ }
+}
+
+class RC2 extends React.Component<{ x: string }, {}> {
+ render() {
+ return null;
+ }
+ private method() { }
+}
+
+class RC3 extends React.Component<{}, {}> {
+ render() {
+ return null;
+ }
+}
+
+class RC4 extends React.Component<{}, {}> {
+ render() {
+ return null;
+ }
+}
+
+var RCComp = RC1 || RC2;
+var EmptyRCComp = RC3 || RC4;
+var PartRCComp = RC1 || RC4;
+// Error
+let a = ;
+let b =
+let c = ;
diff --git a/tests/cases/conformance/jsx/tsxUnionElementType5.tsx b/tests/cases/conformance/jsx/tsxUnionElementType5.tsx
new file mode 100644
index 00000000000..9341bc5805a
--- /dev/null
+++ b/tests/cases/conformance/jsx/tsxUnionElementType5.tsx
@@ -0,0 +1,25 @@
+// @filename: file.tsx
+// @jsx: react
+// @noLib: true
+// @libFiles: react.d.ts,lib.d.ts
+
+import React = require('react');
+
+function EmptySFC1() {
+ return hello
;
+}
+
+function EmptySFC2() {
+ return Hello
;
+}
+
+function SFC2(prop: { x: boolean }) {
+ return World
;
+}
+
+var EmptySFCComp = EmptySFC1 || EmptySFC2;
+var SFC2AndEmptyComp = SFC2 || EmptySFC1;
+
+let a =
+let a1 =
+let b =
\ No newline at end of file
diff --git a/tests/cases/conformance/jsx/tsxUnionElementType6.tsx b/tests/cases/conformance/jsx/tsxUnionElementType6.tsx
new file mode 100644
index 00000000000..99d7b980894
--- /dev/null
+++ b/tests/cases/conformance/jsx/tsxUnionElementType6.tsx
@@ -0,0 +1,27 @@
+// @filename: file.tsx
+// @jsx: react
+// @noLib: true
+// @libFiles: react.d.ts,lib.d.ts
+
+import React = require('react');
+
+function EmptySFC1() {
+ return Hi
+}
+
+function EmptySFC2() {
+ return Hello
+}
+
+function SFC2(prop: { x: boolean }) {
+ return World
;
+}
+
+var EmptySFCComp = EmptySFC1 || EmptySFC2;
+var SFC2AndEmptyComp = SFC2 || EmptySFC1;
+// Error
+let a = ;
+let b = ;
+let c = ;
+let d = ;
+