diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 861279b222571..14e789f17aec5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13548,6 +13548,20 @@ namespace ts { return _jsxElementChildrenPropertyName; } + function getApparentTypeOfJsxPropsType(propsType: Type): Type { + if (!propsType) { + return undefined; + } + if (propsType.flags & TypeFlags.Intersection) { + const propsApparentType: Type[] = []; + for (const t of (propsType).types) { + propsApparentType.push(getApparentType(t)); + } + return getIntersectionType(propsApparentType); + } + return getApparentType(propsType); + } + /** * Get JSX attributes type by trying to resolve openingLikeElement as a stateless function component. * Return only attributes type of successfully resolved call signature. @@ -13568,6 +13582,7 @@ namespace ts { if (callSignature !== unknownSignature) { const callReturnType = callSignature && getReturnTypeOfSignature(callSignature); let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0])); + paramType = getApparentTypeOfJsxPropsType(paramType); if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) { // Intersect in JSX.IntrinsicAttributes if it exists const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); @@ -13605,7 +13620,8 @@ namespace ts { let allMatchingAttributesType: Type; for (const candidate of candidatesOutArray) { const callReturnType = getReturnTypeOfSignature(candidate); - const paramType = callReturnType && (candidate.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(candidate.parameters[0])); + let paramType = callReturnType && (candidate.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(candidate.parameters[0])); + paramType = getApparentTypeOfJsxPropsType(paramType); if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) { let shouldBeCandidate = true; for (const attribute of openingLikeElement.attributes.properties) { diff --git a/tests/baselines/reference/tsxGenericAttributesType1.js b/tests/baselines/reference/tsxGenericAttributesType1.js new file mode 100644 index 0000000000000..5d3d388396afd --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType1.js @@ -0,0 +1,28 @@ +//// [file.tsx] +import React = require('react'); + +const decorator = function (Component: React.StatelessComponent): React.StatelessComponent { + return (props) => +}; + +const decorator2 = function (Component: React.StatelessComponent): React.StatelessComponent { + return (props) => +}; + +const decorator3 = function (Component: React.StatelessComponent): React.StatelessComponent { + return (props) => +}; + +//// [file.jsx] +"use strict"; +exports.__esModule = true; +var React = require("react"); +var decorator = function (Component) { + return function (props) { return ; }; +}; +var decorator2 = function (Component) { + return function (props) { return ; }; +}; +var decorator3 = function (Component) { + return function (props) { return ; }; +}; diff --git a/tests/baselines/reference/tsxGenericAttributesType1.symbols b/tests/baselines/reference/tsxGenericAttributesType1.symbols new file mode 100644 index 0000000000000..473de9b5c72b5 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType1.symbols @@ -0,0 +1,66 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +const decorator = function (Component: React.StatelessComponent): React.StatelessComponent { +>decorator : Symbol(decorator, Decl(file.tsx, 2, 5)) +>T : Symbol(T, Decl(file.tsx, 2, 28)) +>Component : Symbol(Component, Decl(file.tsx, 2, 31)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40)) +>T : Symbol(T, Decl(file.tsx, 2, 28)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40)) +>T : Symbol(T, Decl(file.tsx, 2, 28)) + + return (props) => +>props : Symbol(props, Decl(file.tsx, 3, 12)) +>Component : Symbol(Component, Decl(file.tsx, 2, 31)) +>props : Symbol(props, Decl(file.tsx, 3, 12)) +>Component : Symbol(Component, Decl(file.tsx, 2, 31)) + +}; + +const decorator2 = function (Component: React.StatelessComponent): React.StatelessComponent { +>decorator2 : Symbol(decorator2, Decl(file.tsx, 6, 5)) +>T : Symbol(T, Decl(file.tsx, 6, 29)) +>x : Symbol(x, Decl(file.tsx, 6, 40)) +>Component : Symbol(Component, Decl(file.tsx, 6, 54)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40)) +>T : Symbol(T, Decl(file.tsx, 6, 29)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40)) +>T : Symbol(T, Decl(file.tsx, 6, 29)) + + return (props) => +>props : Symbol(props, Decl(file.tsx, 7, 12)) +>Component : Symbol(Component, Decl(file.tsx, 6, 54)) +>props : Symbol(props, Decl(file.tsx, 7, 12)) +>x : Symbol(x, Decl(file.tsx, 7, 43)) +>Component : Symbol(Component, Decl(file.tsx, 6, 54)) + +}; + +const decorator3 = function (Component: React.StatelessComponent): React.StatelessComponent { +>decorator3 : Symbol(decorator3, Decl(file.tsx, 10, 5)) +>T : Symbol(T, Decl(file.tsx, 10, 29)) +>x : Symbol(x, Decl(file.tsx, 10, 40)) +>U : Symbol(U, Decl(file.tsx, 10, 53)) +>x : Symbol(x, Decl(file.tsx, 10, 65)) +>Component : Symbol(Component, Decl(file.tsx, 10, 80)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40)) +>T : Symbol(T, Decl(file.tsx, 10, 29)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40)) +>T : Symbol(T, Decl(file.tsx, 10, 29)) + + return (props) => +>props : Symbol(props, Decl(file.tsx, 11, 12)) +>Component : Symbol(Component, Decl(file.tsx, 10, 80)) +>x : Symbol(x, Decl(file.tsx, 11, 32)) +>props : Symbol(props, Decl(file.tsx, 11, 12)) +>Component : Symbol(Component, Decl(file.tsx, 10, 80)) + +}; diff --git a/tests/baselines/reference/tsxGenericAttributesType1.types b/tests/baselines/reference/tsxGenericAttributesType1.types new file mode 100644 index 0000000000000..50be358302ea6 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType1.types @@ -0,0 +1,77 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : typeof React + +const decorator = function (Component: React.StatelessComponent): React.StatelessComponent { +>decorator : (Component: React.StatelessComponent) => React.StatelessComponent +>function (Component: React.StatelessComponent): React.StatelessComponent { return (props) => } : (Component: React.StatelessComponent) => React.StatelessComponent +>T : T +>Component : React.StatelessComponent +>React : any +>StatelessComponent : React.StatelessComponent

+>T : T +>React : any +>StatelessComponent : React.StatelessComponent

+>T : T + + return (props) => +>(props) => : (props: T & { children?: React.ReactNode; }) => JSX.Element +>props : T & { children?: React.ReactNode; } +> : JSX.Element +>Component : React.StatelessComponent +>props : T & { children?: React.ReactNode; } +>Component : React.StatelessComponent + +}; + +const decorator2 = function (Component: React.StatelessComponent): React.StatelessComponent { +>decorator2 : (Component: React.StatelessComponent) => React.StatelessComponent +>function (Component: React.StatelessComponent): React.StatelessComponent { return (props) => } : (Component: React.StatelessComponent) => React.StatelessComponent +>T : T +>x : number +>Component : React.StatelessComponent +>React : any +>StatelessComponent : React.StatelessComponent

+>T : T +>React : any +>StatelessComponent : React.StatelessComponent

+>T : T + + return (props) => +>(props) => : (props: T & { children?: React.ReactNode; }) => JSX.Element +>props : T & { children?: React.ReactNode; } +> : JSX.Element +>Component : React.StatelessComponent +>props : T & { children?: React.ReactNode; } +>x : number +>2 : 2 +>Component : React.StatelessComponent + +}; + +const decorator3 = function (Component: React.StatelessComponent): React.StatelessComponent { +>decorator3 : (Component: React.StatelessComponent) => React.StatelessComponent +>function (Component: React.StatelessComponent): React.StatelessComponent { return (props) => } : (Component: React.StatelessComponent) => React.StatelessComponent +>T : T +>x : number +>U : U +>x : number +>Component : React.StatelessComponent +>React : any +>StatelessComponent : React.StatelessComponent

+>T : T +>React : any +>StatelessComponent : React.StatelessComponent

+>T : T + + return (props) => +>(props) => : (props: T & { children?: React.ReactNode; }) => JSX.Element +>props : T & { children?: React.ReactNode; } +> : JSX.Element +>Component : React.StatelessComponent +>x : number +>2 : 2 +>props : T & { children?: React.ReactNode; } +>Component : React.StatelessComponent + +}; diff --git a/tests/baselines/reference/tsxGenericAttributesType2.errors.txt b/tests/baselines/reference/tsxGenericAttributesType2.errors.txt new file mode 100644 index 0000000000000..cbd926c9b6921 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType2.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/jsx/file.tsx(4,45): error TS2339: Property 'y' does not exist on type 'IntrinsicAttributes & { x: number; } & { children?: ReactNode; }'. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + import React = require('react'); + + const decorator4 = function (Component: React.StatelessComponent): React.StatelessComponent { + return (props) => + ~~~~~~~~~~ +!!! error TS2339: Property 'y' does not exist on type 'IntrinsicAttributes & { x: number; } & { children?: ReactNode; }'. + }; \ No newline at end of file diff --git a/tests/baselines/reference/tsxGenericAttributesType2.js b/tests/baselines/reference/tsxGenericAttributesType2.js new file mode 100644 index 0000000000000..7b46d08c2c4de --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType2.js @@ -0,0 +1,14 @@ +//// [file.tsx] +import React = require('react'); + +const decorator4 = function (Component: React.StatelessComponent): React.StatelessComponent { + return (props) => +}; + +//// [file.jsx] +"use strict"; +exports.__esModule = true; +var React = require("react"); +var decorator4 = function (Component) { + return function (props) { return ; }; +}; diff --git a/tests/baselines/reference/tsxGenericAttributesType3.js b/tests/baselines/reference/tsxGenericAttributesType3.js new file mode 100644 index 0000000000000..51491d99aa2a1 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType3.js @@ -0,0 +1,48 @@ +//// [file.tsx] +import React = require('react'); + +class B1 extends React.Component { + render() { + return

hi
; + } +} +class B extends React.Component { + render() { + return ; + } +} + +//// [file.jsx] +"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 __()); + }; +})(); +exports.__esModule = true; +var React = require("react"); +var B1 = (function (_super) { + __extends(B1, _super); + function B1() { + return _super !== null && _super.apply(this, arguments) || this; + } + B1.prototype.render = function () { + return
hi
; + }; + return B1; +}(React.Component)); +var B = (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.render = function () { + return ; + }; + return B; +}(React.Component)); diff --git a/tests/baselines/reference/tsxGenericAttributesType3.symbols b/tests/baselines/reference/tsxGenericAttributesType3.symbols new file mode 100644 index 0000000000000..8c235257e8d49 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType3.symbols @@ -0,0 +1,41 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +class B1 extends React.Component { +>B1 : Symbol(B1, Decl(file.tsx, 0, 32)) +>T : Symbol(T, Decl(file.tsx, 2, 9)) +>x : Symbol(x, Decl(file.tsx, 2, 20)) +>x : Symbol(x, Decl(file.tsx, 2, 36)) +>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)) +>T : Symbol(T, Decl(file.tsx, 2, 9)) + + render() { +>render : Symbol(B1.render, Decl(file.tsx, 2, 82)) + + return
hi
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) + } +} +class B extends React.Component { +>B : Symbol(B, Decl(file.tsx, 6, 1)) +>U : Symbol(U, Decl(file.tsx, 7, 8)) +>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)) +>U : Symbol(U, Decl(file.tsx, 7, 8)) + + render() { +>render : Symbol(B.render, Decl(file.tsx, 7, 43)) + + return ; +>B1 : Symbol(B1, Decl(file.tsx, 0, 32)) +>this.props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37)) +>this : Symbol(B, Decl(file.tsx, 6, 1)) +>props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37)) +>x : Symbol(x, Decl(file.tsx, 9, 34)) + } +} diff --git a/tests/baselines/reference/tsxGenericAttributesType3.types b/tests/baselines/reference/tsxGenericAttributesType3.types new file mode 100644 index 0000000000000..72674ac5bf763 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType3.types @@ -0,0 +1,43 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : typeof React + +class B1 extends React.Component { +>B1 : B1 +>T : T +>x : string +>x : string +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>T : T + + render() { +>render : () => JSX.Element + + return
hi
; +>
hi
: JSX.Element +>div : any +>div : any + } +} +class B extends React.Component { +>B : B +>U : U +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>U : U + + render() { +>render : () => JSX.Element + + return ; +> : JSX.Element +>B1 : typeof B1 +>this.props : U & { children?: React.ReactNode; } +>this : this +>props : U & { children?: React.ReactNode; } +>x : string + } +} diff --git a/tests/baselines/reference/tsxGenericAttributesType4.errors.txt b/tests/baselines/reference/tsxGenericAttributesType4.errors.txt new file mode 100644 index 0000000000000..ee91f938b9f8b --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType4.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/jsx/file.tsx(11,36): error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + import React = require('react'); + + class B1 extends React.Component { + render() { + return
hi
; + } + } + class B extends React.Component { + render() { + // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object + return ; + ~~~~~~ +!!! error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxGenericAttributesType4.js b/tests/baselines/reference/tsxGenericAttributesType4.js new file mode 100644 index 0000000000000..a00d03cd61bf0 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType4.js @@ -0,0 +1,50 @@ +//// [file.tsx] +import React = require('react'); + +class B1 extends React.Component { + render() { + return
hi
; + } +} +class B extends React.Component { + render() { + // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object + return ; + } +} + +//// [file.jsx] +"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 __()); + }; +})(); +exports.__esModule = true; +var React = require("react"); +var B1 = (function (_super) { + __extends(B1, _super); + function B1() { + return _super !== null && _super.apply(this, arguments) || this; + } + B1.prototype.render = function () { + return
hi
; + }; + return B1; +}(React.Component)); +var B = (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.render = function () { + // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object + return ; + }; + return B; +}(React.Component)); diff --git a/tests/baselines/reference/tsxGenericAttributesType5.errors.txt b/tests/baselines/reference/tsxGenericAttributesType5.errors.txt new file mode 100644 index 0000000000000..83f07326f92e4 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType5.errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/jsx/file.tsx(12,36): error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + import React = require('react'); + + class B1 extends React.Component { + render() { + return
hi
; + } + } + class B extends React.Component { + props: U; + render() { + // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object + return ; + ~~~~~~ +!!! error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxGenericAttributesType5.js b/tests/baselines/reference/tsxGenericAttributesType5.js new file mode 100644 index 0000000000000..cb535417dd661 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType5.js @@ -0,0 +1,51 @@ +//// [file.tsx] +import React = require('react'); + +class B1 extends React.Component { + render() { + return
hi
; + } +} +class B extends React.Component { + props: U; + render() { + // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object + return ; + } +} + +//// [file.jsx] +"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 __()); + }; +})(); +exports.__esModule = true; +var React = require("react"); +var B1 = (function (_super) { + __extends(B1, _super); + function B1() { + return _super !== null && _super.apply(this, arguments) || this; + } + B1.prototype.render = function () { + return
hi
; + }; + return B1; +}(React.Component)); +var B = (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.render = function () { + // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object + return ; + }; + return B; +}(React.Component)); diff --git a/tests/baselines/reference/tsxGenericAttributesType6.js b/tests/baselines/reference/tsxGenericAttributesType6.js new file mode 100644 index 0000000000000..84cab3e1f94b2 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType6.js @@ -0,0 +1,49 @@ +//// [file.tsx] +import React = require('react'); + +class B1 extends React.Component { + render() { + return
hi
; + } +} +class B extends React.Component { + props: U; + render() { + return ; + } +} + +//// [file.jsx] +"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 __()); + }; +})(); +exports.__esModule = true; +var React = require("react"); +var B1 = (function (_super) { + __extends(B1, _super); + function B1() { + return _super !== null && _super.apply(this, arguments) || this; + } + B1.prototype.render = function () { + return
hi
; + }; + return B1; +}(React.Component)); +var B = (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.render = function () { + return ; + }; + return B; +}(React.Component)); diff --git a/tests/baselines/reference/tsxGenericAttributesType6.symbols b/tests/baselines/reference/tsxGenericAttributesType6.symbols new file mode 100644 index 0000000000000..27c8ed2d6dce4 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType6.symbols @@ -0,0 +1,45 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +class B1 extends React.Component { +>B1 : Symbol(B1, Decl(file.tsx, 0, 32)) +>T : Symbol(T, Decl(file.tsx, 2, 9)) +>x : Symbol(x, Decl(file.tsx, 2, 20)) +>x : Symbol(x, Decl(file.tsx, 2, 36)) +>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)) +>T : Symbol(T, Decl(file.tsx, 2, 9)) + + render() { +>render : Symbol(B1.render, Decl(file.tsx, 2, 82)) + + return
hi
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) + } +} +class B extends React.Component { +>B : Symbol(B, Decl(file.tsx, 6, 1)) +>U : Symbol(U, Decl(file.tsx, 7, 8)) +>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)) +>U : Symbol(U, Decl(file.tsx, 7, 8)) + + props: U; +>props : Symbol(B.props, Decl(file.tsx, 7, 43)) +>U : Symbol(U, Decl(file.tsx, 7, 8)) + + render() { +>render : Symbol(B.render, Decl(file.tsx, 8, 13)) + + return ; +>B1 : Symbol(B1, Decl(file.tsx, 0, 32)) +>this.props : Symbol(B.props, Decl(file.tsx, 7, 43)) +>this : Symbol(B, Decl(file.tsx, 6, 1)) +>props : Symbol(B.props, Decl(file.tsx, 7, 43)) +>x : Symbol(x, Decl(file.tsx, 10, 34)) + } +} diff --git a/tests/baselines/reference/tsxGenericAttributesType6.types b/tests/baselines/reference/tsxGenericAttributesType6.types new file mode 100644 index 0000000000000..662b6299dad85 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType6.types @@ -0,0 +1,47 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : typeof React + +class B1 extends React.Component { +>B1 : B1 +>T : T +>x : string +>x : string +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>T : T + + render() { +>render : () => JSX.Element + + return
hi
; +>
hi
: JSX.Element +>div : any +>div : any + } +} +class B extends React.Component { +>B : B +>U : U +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>U : U + + props: U; +>props : U +>U : U + + render() { +>render : () => JSX.Element + + return ; +> : JSX.Element +>B1 : typeof B1 +>this.props : U +>this : this +>props : U +>x : string + } +} diff --git a/tests/baselines/reference/tsxGenericAttributesType7.js b/tests/baselines/reference/tsxGenericAttributesType7.js new file mode 100644 index 0000000000000..4e254f25e55b4 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType7.js @@ -0,0 +1,22 @@ +//// [file.tsx] +import React = require('react'); + +declare function Component(props: T) : JSX.Element; +const decorator = function (props: U) { + return ; +} + +const decorator1 = function (props: U) { + return ; +} + +//// [file.jsx] +"use strict"; +exports.__esModule = true; +var React = require("react"); +var decorator = function (props) { + return ; +}; +var decorator1 = function (props) { + return ; +}; diff --git a/tests/baselines/reference/tsxGenericAttributesType7.symbols b/tests/baselines/reference/tsxGenericAttributesType7.symbols new file mode 100644 index 0000000000000..e31042bd8439c --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType7.symbols @@ -0,0 +1,35 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +declare function Component(props: T) : JSX.Element; +>Component : Symbol(Component, Decl(file.tsx, 0, 32)) +>T : Symbol(T, Decl(file.tsx, 2, 27)) +>props : Symbol(props, Decl(file.tsx, 2, 30)) +>T : Symbol(T, Decl(file.tsx, 2, 27)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +const decorator = function (props: U) { +>decorator : Symbol(decorator, Decl(file.tsx, 3, 5)) +>U : Symbol(U, Decl(file.tsx, 3, 28)) +>props : Symbol(props, Decl(file.tsx, 3, 31)) +>U : Symbol(U, Decl(file.tsx, 3, 28)) + + return ; +>Component : Symbol(Component, Decl(file.tsx, 0, 32)) +>props : Symbol(props, Decl(file.tsx, 3, 31)) +} + +const decorator1 = function (props: U) { +>decorator1 : Symbol(decorator1, Decl(file.tsx, 7, 5)) +>U : Symbol(U, Decl(file.tsx, 7, 29)) +>x : Symbol(x, Decl(file.tsx, 7, 40)) +>props : Symbol(props, Decl(file.tsx, 7, 52)) +>U : Symbol(U, Decl(file.tsx, 7, 29)) + + return ; +>Component : Symbol(Component, Decl(file.tsx, 0, 32)) +>props : Symbol(props, Decl(file.tsx, 7, 52)) +>x : Symbol(x, Decl(file.tsx, 8, 32)) +} diff --git a/tests/baselines/reference/tsxGenericAttributesType7.types b/tests/baselines/reference/tsxGenericAttributesType7.types new file mode 100644 index 0000000000000..58d853e4881f1 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType7.types @@ -0,0 +1,39 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : typeof React + +declare function Component(props: T) : JSX.Element; +>Component : (props: T) => JSX.Element +>T : T +>props : T +>T : T +>JSX : any +>Element : JSX.Element + +const decorator = function (props: U) { +>decorator : (props: U) => JSX.Element +>function (props: U) { return ;} : (props: U) => JSX.Element +>U : U +>props : U +>U : U + + return ; +> : JSX.Element +>Component : (props: T) => JSX.Element +>props : U +} + +const decorator1 = function (props: U) { +>decorator1 : (props: U) => JSX.Element +>function (props: U) { return ;} : (props: U) => JSX.Element +>U : U +>x : string +>props : U +>U : U + + return ; +> : JSX.Element +>Component : (props: T) => JSX.Element +>props : U +>x : string +} diff --git a/tests/baselines/reference/tsxGenericAttributesType8.js b/tests/baselines/reference/tsxGenericAttributesType8.js new file mode 100644 index 0000000000000..435bf425c6ab7 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType8.js @@ -0,0 +1,22 @@ +//// [file.tsx] +import React = require('react'); + +declare function Component(props: T) : JSX.Element; +const decorator = function (props: U) { + return ; +} + +const decorator1 = function (props: U) { + return ; +} + +//// [file.jsx] +"use strict"; +exports.__esModule = true; +var React = require("react"); +var decorator = function (props) { + return ; +}; +var decorator1 = function (props) { + return ; +}; diff --git a/tests/baselines/reference/tsxGenericAttributesType8.symbols b/tests/baselines/reference/tsxGenericAttributesType8.symbols new file mode 100644 index 0000000000000..516dbe9c32218 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType8.symbols @@ -0,0 +1,34 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +declare function Component(props: T) : JSX.Element; +>Component : Symbol(Component, Decl(file.tsx, 0, 32)) +>T : Symbol(T, Decl(file.tsx, 2, 27)) +>props : Symbol(props, Decl(file.tsx, 2, 30)) +>T : Symbol(T, Decl(file.tsx, 2, 27)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +const decorator = function (props: U) { +>decorator : Symbol(decorator, Decl(file.tsx, 3, 5)) +>U : Symbol(U, Decl(file.tsx, 3, 28)) +>props : Symbol(props, Decl(file.tsx, 3, 31)) +>U : Symbol(U, Decl(file.tsx, 3, 28)) + + return ; +>Component : Symbol(Component, Decl(file.tsx, 0, 32)) +>props : Symbol(props, Decl(file.tsx, 3, 31)) +} + +const decorator1 = function (props: U) { +>decorator1 : Symbol(decorator1, Decl(file.tsx, 7, 5)) +>U : Symbol(U, Decl(file.tsx, 7, 29)) +>x : Symbol(x, Decl(file.tsx, 7, 40)) +>props : Symbol(props, Decl(file.tsx, 7, 52)) +>U : Symbol(U, Decl(file.tsx, 7, 29)) + + return ; +>Component : Symbol(Component, Decl(file.tsx, 0, 32)) +>props : Symbol(props, Decl(file.tsx, 7, 52)) +} diff --git a/tests/baselines/reference/tsxGenericAttributesType8.types b/tests/baselines/reference/tsxGenericAttributesType8.types new file mode 100644 index 0000000000000..b2a62a575ff9d --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType8.types @@ -0,0 +1,38 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : typeof React + +declare function Component(props: T) : JSX.Element; +>Component : (props: T) => JSX.Element +>T : T +>props : T +>T : T +>JSX : any +>Element : JSX.Element + +const decorator = function (props: U) { +>decorator : (props: U) => JSX.Element +>function (props: U) { return ;} : (props: U) => JSX.Element +>U : U +>props : U +>U : U + + return ; +> : JSX.Element +>Component : (props: T) => JSX.Element +>props : U +} + +const decorator1 = function (props: U) { +>decorator1 : (props: U) => JSX.Element +>function (props: U) { return ;} : (props: U) => JSX.Element +>U : U +>x : string +>props : U +>U : U + + return ; +> : JSX.Element +>Component : (props: T) => JSX.Element +>props : U +} diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents3.types b/tests/baselines/reference/tsxStatelessFunctionComponents3.types index 714781058ebcc..879f8c75cdf72 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents3.types +++ b/tests/baselines/reference/tsxStatelessFunctionComponents3.types @@ -21,8 +21,8 @@ var MainMenu: React.StatelessComponent<{}> = (props) => (
>MainMenu : React.StatelessComponent<{}> >React : any >StatelessComponent : React.StatelessComponent

->(props) => (

Main Menu

) : (props: {}) => JSX.Element ->props : {} +>(props) => (

Main Menu

) : (props: { children?: React.ReactNode; }) => JSX.Element +>props : { children?: React.ReactNode; } >(

Main Menu

) : JSX.Element >

Main Menu

: JSX.Element >div : any @@ -40,7 +40,7 @@ var App: React.StatelessComponent<{ children }> = ({children}) => ( >React : any >StatelessComponent : React.StatelessComponent

>children : any ->({children}) => (

) : ({children}: { children: any; }) => JSX.Element +>({children}) => (
) : ({children}: { children: any; } & { children?: React.ReactNode; }) => JSX.Element >children : any >(
) : JSX.Element diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType1.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType1.tsx new file mode 100644 index 0000000000000..e6b7fc18ef718 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType1.tsx @@ -0,0 +1,18 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +const decorator = function (Component: React.StatelessComponent): React.StatelessComponent { + return (props) => +}; + +const decorator2 = function (Component: React.StatelessComponent): React.StatelessComponent { + return (props) => +}; + +const decorator3 = function (Component: React.StatelessComponent): React.StatelessComponent { + return (props) => +}; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType2.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType2.tsx new file mode 100644 index 0000000000000..48acd55546f03 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType2.tsx @@ -0,0 +1,10 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +const decorator4 = function (Component: React.StatelessComponent): React.StatelessComponent { + return (props) => +}; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType3.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType3.tsx new file mode 100644 index 0000000000000..b683c5e79708b --- /dev/null +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType3.tsx @@ -0,0 +1,17 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +class B1 extends React.Component { + render() { + return
hi
; + } +} +class B extends React.Component { + render() { + return ; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx new file mode 100644 index 0000000000000..b207f2b4398ce --- /dev/null +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx @@ -0,0 +1,18 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +class B1 extends React.Component { + render() { + return
hi
; + } +} +class B extends React.Component { + render() { + // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object + return ; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx new file mode 100644 index 0000000000000..d0215da739758 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx @@ -0,0 +1,19 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +class B1 extends React.Component { + render() { + return
hi
; + } +} +class B extends React.Component { + props: U; + render() { + // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object + return ; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType6.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType6.tsx new file mode 100644 index 0000000000000..d70df8a0cf743 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType6.tsx @@ -0,0 +1,18 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +class B1 extends React.Component { + render() { + return
hi
; + } +} +class B extends React.Component { + props: U; + render() { + return ; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType7.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType7.tsx new file mode 100644 index 0000000000000..3044fda23df77 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType7.tsx @@ -0,0 +1,15 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +declare function Component(props: T) : JSX.Element; +const decorator = function (props: U) { + return ; +} + +const decorator1 = function (props: U) { + return ; +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType8.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType8.tsx new file mode 100644 index 0000000000000..b1d3a7445c898 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType8.tsx @@ -0,0 +1,15 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +declare function Component(props: T) : JSX.Element; +const decorator = function (props: U) { + return ; +} + +const decorator1 = function (props: U) { + return ; +} \ No newline at end of file diff --git a/tests/lib/react.d.ts b/tests/lib/react.d.ts index 1d7b787b9994d..7f03899eb6c6a 100644 --- a/tests/lib/react.d.ts +++ b/tests/lib/react.d.ts @@ -197,7 +197,7 @@ declare namespace __React { type SFC

= StatelessComponent

; interface StatelessComponent

{ - (props: P, context?: any): ReactElement; + (props: P & { children?: ReactNode }, context?: any): ReactElement; propTypes?: ValidationMap

; contextTypes?: ValidationMap; defaultProps?: P;