Elaborate jsx children elementwise (#29264)

* Heavy WIP, but has good contextual typing fix

* Add arity error, refine messages and spans

* Small error message change

* Better error messages, text-specific message
This commit is contained in:
Wesley Wigham 2019-01-15 11:32:36 -08:00 committed by GitHub
parent 35f64fa894
commit 49689894d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 883 additions and 141 deletions

View file

@ -11196,7 +11196,7 @@ namespace ts {
case SyntaxKind.ArrayLiteralExpression:
return elaborateArrayLiteral(node as ArrayLiteralExpression, source, target, relation);
case SyntaxKind.JsxAttributes:
return elaborateJsxAttributes(node as JsxAttributes, source, target, relation);
return elaborateJsxComponents(node as JsxAttributes, source, target, relation);
case SyntaxKind.ArrowFunction:
return elaborateArrowFunction(node as ArrowFunction, source, target, relation);
}
@ -11336,8 +11336,113 @@ namespace ts {
}
}
function elaborateJsxAttributes(node: JsxAttributes, source: Type, target: Type, relation: Map<RelationComparisonResult>) {
return elaborateElementwise(generateJsxAttributes(node), source, target, relation);
function *generateJsxChildren(node: JsxElement, getInvalidTextDiagnostic: () => DiagnosticMessage): ElaborationIterator {
if (!length(node.children)) return;
let memberOffset = 0;
for (let i = 0; i < node.children.length; i++) {
const child = node.children[i];
const nameType = getLiteralType(i - memberOffset);
const elem = getElaborationElementForJsxChild(child, nameType, getInvalidTextDiagnostic);
if (elem) {
yield elem;
}
else {
memberOffset++;
}
}
}
function getElaborationElementForJsxChild(child: JsxChild, nameType: LiteralType, getInvalidTextDiagnostic: () => DiagnosticMessage) {
switch (child.kind) {
case SyntaxKind.JsxExpression:
// child is of the type of the expression
return { errorNode: child, innerExpression: child.expression, nameType };
case SyntaxKind.JsxText:
if (child.containsOnlyWhiteSpaces) {
break; // Whitespace only jsx text isn't real jsx text
}
// child is a string
return { errorNode: child, innerExpression: undefined, nameType, errorMessage: getInvalidTextDiagnostic() };
case SyntaxKind.JsxElement:
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxFragment:
// child is of type JSX.Element
return { errorNode: child, innerExpression: child, nameType };
default:
return Debug.assertNever(child, "Found invalid jsx child");
}
}
function elaborateJsxComponents(node: JsxAttributes, source: Type, target: Type, relation: Map<RelationComparisonResult>) {
let result = elaborateElementwise(generateJsxAttributes(node), source, target, relation);
let invalidTextDiagnostic: DiagnosticMessage | undefined;
if (isJsxOpeningElement(node.parent) && isJsxElement(node.parent.parent)) {
const containingElement = node.parent.parent;
const childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
const childrenPropName = childPropName === undefined ? "children" : unescapeLeadingUnderscores(childPropName);
const childrenNameType = getLiteralType(childrenPropName);
const childrenTargetType = getIndexedAccessType(target, childrenNameType);
const validChildren = filter(containingElement.children, i => !isJsxText(i) || !i.containsOnlyWhiteSpaces);
if (!length(validChildren)) {
return result;
}
const moreThanOneRealChildren = length(validChildren) > 1;
const arrayLikeTargetParts = filterType(childrenTargetType, isArrayOrTupleLikeType);
const nonArrayLikeTargetParts = filterType(childrenTargetType, t => !isArrayOrTupleLikeType(t));
if (moreThanOneRealChildren) {
if (arrayLikeTargetParts !== neverType) {
const realSource = createTupleType(checkJsxChildren(containingElement, CheckMode.Normal));
result = elaborateElementwise(generateJsxChildren(containingElement, getInvalidTextualChildDiagnostic), realSource, arrayLikeTargetParts, relation) || result;
}
else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) {
// arity mismatch
result = true;
error(
containingElement.openingElement.tagName,
Diagnostics.This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided,
childrenPropName,
typeToString(childrenTargetType)
);
}
}
else {
if (nonArrayLikeTargetParts !== neverType) {
const child = validChildren[0];
const elem = getElaborationElementForJsxChild(child, childrenNameType, getInvalidTextualChildDiagnostic);
if (elem) {
result = elaborateElementwise(
(function*() { yield elem; })(),
source,
target,
relation
) || result;
}
}
else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) {
// arity mismatch
result = true;
error(
containingElement.openingElement.tagName,
Diagnostics.This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided,
childrenPropName,
typeToString(childrenTargetType)
);
}
}
}
return result;
function getInvalidTextualChildDiagnostic() {
if (!invalidTextDiagnostic) {
const tagNameText = getTextOfNode(node.parent.tagName);
const childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
const childrenPropName = childPropName === undefined ? "children" : unescapeLeadingUnderscores(childPropName);
const childrenTargetType = getIndexedAccessType(target, getLiteralType(childrenPropName));
const diagnostic = Diagnostics._0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2;
invalidTextDiagnostic = { ...diagnostic, key: "!!ALREADY FORMATTED!!", message: formatMessage(/*_dummy*/ undefined, diagnostic, tagNameText, childrenPropName, typeToString(childrenTargetType)) };
}
return invalidTextDiagnostic;
}
}
function *generateLimitedTupleElements(node: ArrayLiteralExpression, target: Type): ElaborationIterator {
@ -13477,6 +13582,10 @@ namespace ts {
return isTupleType(type) || !!getPropertyOfType(type, "0" as __String);
}
function isArrayOrTupleLikeType(type: Type): boolean {
return isArrayLikeType(type) || isTupleLikeType(type);
}
function getTupleElementType(type: Type, index: number) {
const propType = getTypeOfPropertyOfType(type, "" + index as __String);
if (propType) {
@ -17492,11 +17601,23 @@ namespace ts {
return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined;
}
function getContextualTypeForChildJsxExpression(node: JsxElement) {
function getContextualTypeForChildJsxExpression(node: JsxElement, child: JsxChild) {
const attributesType = getApparentTypeOfContextualType(node.openingElement.tagName);
// JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty)
const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
return attributesType && !isTypeAny(attributesType) && jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName) : undefined;
if (!(attributesType && !isTypeAny(attributesType) && jsxChildrenPropertyName && jsxChildrenPropertyName !== "")) {
return undefined;
}
const childIndex = node.children.indexOf(child);
const childFieldType = getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName);
return childFieldType && mapType(childFieldType, t => {
if (isArrayLikeType(t)) {
return getIndexedAccessType(t, getLiteralType(childIndex));
}
else {
return t;
}
}, /*noReductions*/ true);
}
function getContextualTypeForJsxExpression(node: JsxExpression): Type | undefined {
@ -17504,7 +17625,7 @@ namespace ts {
return isJsxAttributeLike(exprParent)
? getContextualType(node)
: isJsxElement(exprParent)
? getContextualTypeForChildJsxExpression(exprParent)
? getContextualTypeForChildJsxExpression(exprParent, node)
: undefined;
}

View file

@ -2541,6 +2541,18 @@
"category": "Error",
"code": 2744
},
"This JSX tag's '{0}' prop expects type '{1}' which requires multiple children, but only a single child was provided.": {
"category": "Error",
"code": 2745
},
"This JSX tag's '{0}' prop expects a single child of type '{1}', but multiple children were provided.": {
"category": "Error",
"code": 2746
},
"'{0}' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of '{1}' is '{2}'.": {
"category": "Error",
"code": 2747
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",

View file

@ -888,7 +888,7 @@ namespace ts {
}
const isMissing = nodeIsMissing(errorNode);
const pos = isMissing
const pos = isMissing || isJsxText(node)
? errorNode.pos
: skipTrivia(sourceFile.text, errorNode.pos);
@ -7024,6 +7024,7 @@ namespace ts {
};
}
export function formatMessage(_dummy: any, message: DiagnosticMessage, ...args: (string | number | undefined)[]): string;
export function formatMessage(_dummy: any, message: DiagnosticMessage): string {
let text = getLocaleSpecificMessage(message);

View file

@ -1,6 +1,4 @@
tests/cases/conformance/jsx/file.tsx(42,11): error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'SingleChildProp'.
Types of property 'children' are incompatible.
Type 'Element[]' is missing the following properties from type 'Element': type, props
tests/cases/conformance/jsx/file.tsx(42,11): error TS2746: This JSX tag's 'children' prop expects a single child of type 'Element', but multiple children were provided.
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
@ -47,6 +45,4 @@ tests/cases/conformance/jsx/file.tsx(42,11): error TS2322: Type '{ children: Ele
// Error
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
~~~~~~~~~~~~~~~
!!! error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'SingleChildProp'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type 'Element[]' is missing the following properties from type 'Element': type, props
!!! error TS2746: This JSX tag's 'children' prop expects a single child of type 'Element', but multiple children were provided.

View file

@ -1,21 +1,9 @@
tests/cases/conformance/jsx/file.tsx(14,10): error TS2741: Property 'children' is missing in type '{ a: number; b: string; }' but required in type 'Prop'.
tests/cases/conformance/jsx/file.tsx(17,11): error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten.
tests/cases/conformance/jsx/file.tsx(31,6): error TS2322: Type '{ children: (Element | ((name: string) => Element))[]; a: number; b: string; }' is not assignable to type 'Prop'.
Types of property 'children' are incompatible.
Type '(Element | ((name: string) => Element))[]' is not assignable to type 'string | Element'.
Type '(Element | ((name: string) => Element))[]' is not assignable to type 'string'.
tests/cases/conformance/jsx/file.tsx(37,6): error TS2322: Type '{ children: (number | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
Types of property 'children' are incompatible.
Type '(number | Element)[]' is not assignable to type 'string | Element'.
Type '(number | Element)[]' is not assignable to type 'string'.
tests/cases/conformance/jsx/file.tsx(43,6): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
Types of property 'children' are incompatible.
Type '(string | Element)[]' is not assignable to type 'string | Element'.
Type '(string | Element)[]' is not assignable to type 'string'.
tests/cases/conformance/jsx/file.tsx(49,6): error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'Prop'.
Types of property 'children' are incompatible.
Type 'Element[]' is not assignable to type 'string | Element'.
Type 'Element[]' is not assignable to type 'string'.
tests/cases/conformance/jsx/file.tsx(31,6): error TS2746: This JSX tag's 'children' prop expects a single child of type 'string | Element', but multiple children were provided.
tests/cases/conformance/jsx/file.tsx(37,6): error TS2746: This JSX tag's 'children' prop expects a single child of type 'string | Element', but multiple children were provided.
tests/cases/conformance/jsx/file.tsx(43,6): error TS2746: This JSX tag's 'children' prop expects a single child of type 'string | Element', but multiple children were provided.
tests/cases/conformance/jsx/file.tsx(49,6): error TS2746: This JSX tag's 'children' prop expects a single child of type 'string | Element', but multiple children were provided.
==== tests/cases/conformance/jsx/file.tsx (6 errors) ====
@ -56,10 +44,7 @@ tests/cases/conformance/jsx/file.tsx(49,6): error TS2322: Type '{ children: Elem
let k2 =
<Comp a={10} b="hi">
~~~~
!!! error TS2322: Type '{ children: (Element | ((name: string) => Element))[]; a: number; b: string; }' is not assignable to type 'Prop'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type '(Element | ((name: string) => Element))[]' is not assignable to type 'string | Element'.
!!! error TS2322: Type '(Element | ((name: string) => Element))[]' is not assignable to type 'string'.
!!! error TS2746: This JSX tag's 'children' prop expects a single child of type 'string | Element', but multiple children were provided.
<div> My Div </div>
{(name: string) => <div> My name {name} </div>}
</Comp>;
@ -67,10 +52,7 @@ tests/cases/conformance/jsx/file.tsx(49,6): error TS2322: Type '{ children: Elem
let k3 =
<Comp a={10} b="hi">
~~~~
!!! error TS2322: Type '{ children: (number | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type '(number | Element)[]' is not assignable to type 'string | Element'.
!!! error TS2322: Type '(number | Element)[]' is not assignable to type 'string'.
!!! error TS2746: This JSX tag's 'children' prop expects a single child of type 'string | Element', but multiple children were provided.
<div> My Div </div>
{1000000}
</Comp>;
@ -78,10 +60,7 @@ tests/cases/conformance/jsx/file.tsx(49,6): error TS2322: Type '{ children: Elem
let k4 =
<Comp a={10} b="hi" >
~~~~
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'string | Element'.
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'string'.
!!! error TS2746: This JSX tag's 'children' prop expects a single child of type 'string | Element', but multiple children were provided.
<div> My Div </div>
hi hi hi!
</Comp>;
@ -89,10 +68,7 @@ tests/cases/conformance/jsx/file.tsx(49,6): error TS2322: Type '{ children: Elem
let k5 =
<Comp a={10} b="hi" >
~~~~
!!! error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'Prop'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type 'Element[]' is not assignable to type 'string | Element'.
!!! error TS2322: Type 'Element[]' is not assignable to type 'string'.
!!! error TS2746: This JSX tag's 'children' prop expects a single child of type 'string | Element', but multiple children were provided.
<div> My Div </div>
<div> My Div </div>
</Comp>;

View file

@ -1,11 +1,11 @@
tests/cases/conformance/jsx/file.tsx(24,28): error TS2551: Property 'NAme' does not exist on type 'IUser'. Did you mean 'Name'?
tests/cases/conformance/jsx/file.tsx(32,10): error TS2322: Type '{ children: (((user: IUser) => Element) | ((user: IUser) => Element))[]; }' is not assignable to type 'IFetchUserProps'.
Types of property 'children' are incompatible.
Type '(((user: IUser) => Element) | ((user: IUser) => Element))[]' is not assignable to type '(user: IUser) => Element'.
Type '(((user: IUser) => Element) | ((user: IUser) => Element))[]' provides no match for the signature '(user: IUser): Element'.
tests/cases/conformance/jsx/file.tsx(36,15): error TS2322: Type '(user: IUser) => Element' is not assignable to type 'string | number | boolean | any[] | ReactElement<any>'.
Type '(user: IUser) => Element' is missing the following properties from type 'ReactElement<any>': type, props
tests/cases/conformance/jsx/file.tsx(39,15): error TS2322: Type '(user: IUser) => Element' is not assignable to type 'string | number | boolean | any[] | ReactElement<any>'.
Type '(user: IUser) => Element' is missing the following properties from type 'ReactElement<any>': type, props
==== tests/cases/conformance/jsx/file.tsx (2 errors) ====
==== tests/cases/conformance/jsx/file.tsx (3 errors) ====
import React = require('react');
interface IUser {
@ -41,20 +41,27 @@ tests/cases/conformance/jsx/file.tsx(32,10): error TS2322: Type '{ children: (((
function UserName1() {
return (
<FetchUser>
~~~~~~~~~
!!! error TS2322: Type '{ children: (((user: IUser) => Element) | ((user: IUser) => Element))[]; }' is not assignable to type 'IFetchUserProps'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type '(((user: IUser) => Element) | ((user: IUser) => Element))[]' is not assignable to type '(user: IUser) => Element'.
!!! error TS2322: Type '(((user: IUser) => Element) | ((user: IUser) => Element))[]' provides no match for the signature '(user: IUser): Element'.
{ user => (
~~~~~~~~~
<h1>{ user.Name }</h1>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
) }
~~~~~~~~~~~~~
!!! error TS2322: Type '(user: IUser) => Element' is not assignable to type 'string | number | boolean | any[] | ReactElement<any>'.
!!! error TS2322: Type '(user: IUser) => Element' is missing the following properties from type 'ReactElement<any>': type, props
!!! related TS6212 tests/cases/conformance/jsx/file.tsx:36:15: Did you mean to call this expression?
{ user => (
~~~~~~~~~
<h1>{ user.Name }</h1>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
) }
~~~~~~~~~~~~~
!!! error TS2322: Type '(user: IUser) => Element' is not assignable to type 'string | number | boolean | any[] | ReactElement<any>'.
!!! error TS2322: Type '(user: IUser) => Element' is missing the following properties from type 'ReactElement<any>': type, props
!!! related TS6212 tests/cases/conformance/jsx/file.tsx:39:15: Did you mean to call this expression?
</FetchUser>
);
}

View file

@ -1,10 +1,6 @@
tests/cases/conformance/jsx/file.tsx(20,10): error TS2741: Property 'children' is missing in type '{ a: number; b: string; }' but required in type 'Prop'.
tests/cases/conformance/jsx/file.tsx(24,6): error TS2322: Type '{ children: Element; a: number; b: string; }' is not assignable to type 'Prop'.
Types of property 'children' are incompatible.
Type 'Element' is missing the following properties from type 'Button': render, setState, forceUpdate, state, and 2 more.
tests/cases/conformance/jsx/file.tsx(28,6): error TS2322: Type '{ children: typeof Button; a: number; b: string; }' is not assignable to type 'Prop'.
Types of property 'children' are incompatible.
Type 'typeof Button' is missing the following properties from type 'Button': render, setState, forceUpdate, props, and 3 more.
tests/cases/conformance/jsx/file.tsx(25,9): error TS2740: Type 'Element' is missing the following properties from type 'Button': render, setState, forceUpdate, state, and 2 more.
tests/cases/conformance/jsx/file.tsx(29,10): error TS2740: Type 'typeof Button' is missing the following properties from type 'Button': render, setState, forceUpdate, props, and 3 more.
==== tests/cases/conformance/jsx/file.tsx (3 errors) ====
@ -35,17 +31,15 @@ tests/cases/conformance/jsx/file.tsx(28,6): error TS2322: Type '{ children: type
// Error: JSX.element is not the same as JSX.ElementClass
let k1 =
<Comp a={10} b="hi">
~~~~
!!! error TS2322: Type '{ children: Element; a: number; b: string; }' is not assignable to type 'Prop'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type 'Element' is missing the following properties from type 'Button': render, setState, forceUpdate, state, and 2 more.
<Button />
~~~~~~~~~~
!!! error TS2740: Type 'Element' is missing the following properties from type 'Button': render, setState, forceUpdate, state, and 2 more.
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:6:5: The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & Prop'
</Comp>;
let k2 =
<Comp a={10} b="hi">
~~~~
!!! error TS2322: Type '{ children: typeof Button; a: number; b: string; }' is not assignable to type 'Prop'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type 'typeof Button' is missing the following properties from type 'Button': render, setState, forceUpdate, props, and 3 more.
{Button}
~~~~~~
!!! error TS2740: Type 'typeof Button' is missing the following properties from type 'Button': render, setState, forceUpdate, props, and 3 more.
!!! related TS6213 tests/cases/conformance/jsx/file.tsx:29:10: Did you mean to use 'new' with this expression?
</Comp>;

View file

@ -1,17 +1,6 @@
tests/cases/conformance/jsx/file.tsx(24,11): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
Types of property 'children' are incompatible.
Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
Type '(string | Element)[]' is not assignable to type 'Element[]'.
Type 'string | Element' is not assignable to type 'Element'.
Type 'string' is not assignable to type 'Element'.
tests/cases/conformance/jsx/file.tsx(25,11): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
Types of property 'children' are incompatible.
Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
Type '(string | Element)[]' is not assignable to type 'Element[]'.
tests/cases/conformance/jsx/file.tsx(27,11): error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
Types of property 'children' are incompatible.
Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
Type '(string | Element)[]' is not assignable to type 'Element[]'.
tests/cases/conformance/jsx/file.tsx(24,40): error TS2747: 'Comp' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Element | Element[]'.
tests/cases/conformance/jsx/file.tsx(26,22): error TS2747: 'Comp' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Element | Element[]'.
tests/cases/conformance/jsx/file.tsx(27,30): error TS2747: 'Comp' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Element | Element[]'.
==== tests/cases/conformance/jsx/file.tsx (3 errors) ====
@ -39,24 +28,13 @@ tests/cases/conformance/jsx/file.tsx(27,11): error TS2322: Type '{ children: (st
// Error: whitespaces matters
let k1 = <Comp a={10} b="hi"><Button /> <AnotherButton /></Comp>;
~~~~
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element[]'.
!!! error TS2322: Type 'string | Element' is not assignable to type 'Element'.
!!! error TS2322: Type 'string' is not assignable to type 'Element'.
~~
!!! error TS2747: 'Comp' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Element | Element[]'.
let k2 = <Comp a={10} b="hi"><Button />
~~~~
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element[]'.
<AnotherButton /> </Comp>;
~~
!!! error TS2747: 'Comp' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Element | Element[]'.
let k3 = <Comp a={10} b="hi"> <Button />
~~~~
!!! error TS2322: Type '{ children: (string | Element)[]; a: number; b: string; }' is not assignable to type 'Prop'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element | Element[]'.
!!! error TS2322: Type '(string | Element)[]' is not assignable to type 'Element[]'.
~~~~
!!! error TS2747: 'Comp' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Element | Element[]'.
<AnotherButton /></Comp>;

View file

@ -1,15 +1,11 @@
tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2741: Property '__predomBrand' is missing in type 'Element' but required in type 'Element'.
tests/cases/conformance/jsx/inline/index.tsx(21,22): error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ x: number; y: number; children?: Element[]; }'.
Types of property 'children' are incompatible.
Type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element[]' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element[]'.
Type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'.
tests/cases/conformance/jsx/inline/index.tsx(21,40): error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'.
tests/cases/conformance/jsx/inline/index.tsx(21,40): error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements.
Property '__domBrand' is missing in type 'MyClass' but required in type 'ElementClass'.
tests/cases/conformance/jsx/inline/index.tsx(21,63): error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'.
tests/cases/conformance/jsx/inline/index.tsx(21,63): error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements.
tests/cases/conformance/jsx/inline/index.tsx(24,23): error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ x: number; y: number; children?: Element[]; }'.
Types of property 'children' are incompatible.
Type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element[]' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element[]'.
Property '__domBrand' is missing in type 'Element' but required in type 'Element'.
tests/cases/conformance/jsx/inline/index.tsx(24,42): error TS2741: Property '__domBrand' is missing in type 'Element' but required in type 'Element'.
tests/cases/conformance/jsx/inline/index.tsx(24,48): error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element'.
==== tests/cases/conformance/jsx/inline/renderer.d.ts (0 errors) ====
@ -72,7 +68,7 @@ tests/cases/conformance/jsx/inline/index.tsx(24,23): error TS2322: Type '{ child
export default <h></h>
==== tests/cases/conformance/jsx/inline/index.tsx (5 errors) ====
==== tests/cases/conformance/jsx/inline/index.tsx (7 errors) ====
/** @jsx dom */
import { dom } from "./renderer"
import prerendered, {MySFC, MyClass, tree} from "./component";
@ -97,24 +93,22 @@ tests/cases/conformance/jsx/inline/index.tsx(24,23): error TS2322: Type '{ child
// Should fail, no dom elements
const _brokenTree = <MySFC x={1} y={2}><MyClass x={3} y={4} /><MyClass x={5} y={6} /></MySFC>
~~~~~
!!! error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ x: number; y: number; children?: Element[]; }'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element[]' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element[]'.
!!! error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'.
~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'.
~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements.
!!! error TS2605: Property '__domBrand' is missing in type 'MyClass' but required in type 'ElementClass'.
!!! related TS2728 tests/cases/conformance/jsx/inline/renderer.d.ts:7:13: '__domBrand' is declared here.
~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'.
~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements.
// Should fail, nondom isn't allowed as children of dom
const _brokenTree2 = <DOMSFC x={1} y={2}>{tree}{tree}</DOMSFC>
~~~~~~
!!! error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ x: number; y: number; children?: Element[]; }'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element[]' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element[]'.
!!! error TS2322: Property '__domBrand' is missing in type 'Element' but required in type 'Element'.
~~~~~~
!!! error TS2741: Property '__domBrand' is missing in type 'Element' but required in type 'Element'.
!!! related TS2728 tests/cases/conformance/jsx/inline/renderer.d.ts:7:13: '__domBrand' is declared here.
~~~~~~
!!! error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element'.

View file

@ -1,14 +1,6 @@
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(20,46): error TS2322: Type '"y"' is not assignable to type '"x"'.
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(21,19): error TS2322: Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x">'.
Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'LitProps<"x">'.
Types of property 'children' are incompatible.
Type '(p: IntrinsicAttributes & LitProps<"x">) => "y"' is not assignable to type '(x: LitProps<"x">) => "x"'.
Type '"y"' is not assignable to type '"x"'.
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(22,21): error TS2322: Type '{ children: () => number; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x">'.
Type '{ children: () => number; prop: "x"; }' is not assignable to type 'LitProps<"x">'.
Types of property 'children' are incompatible.
Type '() => number' is not assignable to type '(x: LitProps<"x">) => "x"'.
Type 'number' is not assignable to type '"x"'.
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(21,42): error TS2322: Type '"y"' is not assignable to type '"x"'.
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(22,45): error TS2322: Type 'number' is not assignable to type '"x"'.
==== tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx (3 errors) ====
@ -36,16 +28,10 @@ tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(22,21): error TS2322:
!!! error TS2322: Type '"y"' is not assignable to type '"x"'.
!!! related TS6502 tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx:13:44: The expected type comes from the return type of this signature.
const argchild = <ElemLit prop="x">{p => "y"}</ElemLit>
~~~~~~~
!!! error TS2322: Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x">'.
!!! error TS2322: Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'LitProps<"x">'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type '(p: IntrinsicAttributes & LitProps<"x">) => "y"' is not assignable to type '(x: LitProps<"x">) => "x"'.
!!! error TS2322: Type '"y"' is not assignable to type '"x"'.
~~~
!!! error TS2322: Type '"y"' is not assignable to type '"x"'.
!!! related TS6502 tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx:13:44: The expected type comes from the return type of this signature.
const mismatched = <ElemLit prop="x">{() => 12}</ElemLit>
~~~~~~~
!!! error TS2322: Type '{ children: () => number; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x">'.
!!! error TS2322: Type '{ children: () => number; prop: "x"; }' is not assignable to type 'LitProps<"x">'.
!!! error TS2322: Types of property 'children' are incompatible.
!!! error TS2322: Type '() => number' is not assignable to type '(x: LitProps<"x">) => "x"'.
!!! error TS2322: Type 'number' is not assignable to type '"x"'.
~~
!!! error TS2322: Type 'number' is not assignable to type '"x"'.
!!! related TS6502 tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx:13:44: The expected type comes from the return type of this signature.

View file

@ -0,0 +1,128 @@
tests/cases/compiler/index.tsx(14,9): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/index.tsx(18,15): error TS2747: 'Blah' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is '(x: number) => string'.
tests/cases/compiler/index.tsx(23,10): error TS2746: This JSX tag's 'children' prop expects a single child of type '(x: number) => string', but multiple children were provided.
tests/cases/compiler/index.tsx(37,10): error TS2745: This JSX tag's 'children' prop expects type '((x: number) => string)[]' which requires multiple children, but only a single child was provided.
tests/cases/compiler/index.tsx(42,10): error TS2745: This JSX tag's 'children' prop expects type '((x: number) => string)[]' which requires multiple children, but only a single child was provided.
tests/cases/compiler/index.tsx(48,9): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/index.tsx(49,9): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/index.tsx(63,3): error TS2322: Type '(x: number) => number' is not assignable to type 'Cb | Cb[]'.
Type '(x: number) => number' is not assignable to type 'Cb'.
Type 'number' is not assignable to type 'string'.
tests/cases/compiler/index.tsx(67,16): error TS2747: 'Blah3' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Cb | Cb[]'.
tests/cases/compiler/index.tsx(73,9): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/index.tsx(74,9): error TS2322: Type 'number' is not assignable to type 'string'.
==== tests/cases/compiler/index.tsx (11 errors) ====
/// <reference path="/.lib/react16.d.ts" />
import * as React from "react";
interface Props {
children: (x: number) => string;
}
export function Blah(props: Props) {
return <></>;
}
// Incompatible child.
var a = <Blah>
{x => x}
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! related TS6502 tests/cases/compiler/index.tsx:5:13: The expected type comes from the return type of this signature.
</Blah>
// Blah components don't accept text as child elements
var a = <Blah>
Hello unexpected text!
~~~~~~~~~~~~~~~~~~~~~~~~
</Blah>
!!! error TS2747: 'Blah' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is '(x: number) => string'.
!!! related TS6500 tests/cases/compiler/index.tsx:5:3: The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & Props'
// Blah components don't accept multiple children.
var a = <Blah>
~~~~
!!! error TS2746: This JSX tag's 'children' prop expects a single child of type '(x: number) => string', but multiple children were provided.
{x => "" + x}
{x => "" + x}
</Blah>
interface PropsArr {
children: ((x: number) => string)[];
}
export function Blah2(props: PropsArr) {
return <></>;
}
// Incompatible child.
var a = <Blah2>
~~~~~
!!! error TS2745: This JSX tag's 'children' prop expects type '((x: number) => string)[]' which requires multiple children, but only a single child was provided.
{x => x}
</Blah2>
// Blah2 components don't accept text as child elements
var a = <Blah2>
~~~~~
!!! error TS2745: This JSX tag's 'children' prop expects type '((x: number) => string)[]' which requires multiple children, but only a single child was provided.
Hello unexpected text!
</Blah2>
// Blah2 components don't accept multiple children of the wrong type.
var a = <Blah2>
{x => x}
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! related TS6502 tests/cases/compiler/index.tsx:29:14: The expected type comes from the return type of this signature.
{x => x}
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! related TS6502 tests/cases/compiler/index.tsx:29:14: The expected type comes from the return type of this signature.
</Blah2>
type Cb = (x: number) => string;
interface PropsMixed {
children: Cb | Cb[];
}
export function Blah3(props: PropsMixed) {
return <></>;
}
// Incompatible child.
var a = <Blah3>
{x => x}
~~~~~~~~
!!! error TS2322: Type '(x: number) => number' is not assignable to type 'Cb | Cb[]'.
!!! error TS2322: Type '(x: number) => number' is not assignable to type 'Cb'.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! related TS6500 tests/cases/compiler/index.tsx:54:3: The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & PropsMixed'
</Blah3>
// Blah3 components don't accept text as child elements
var a = <Blah3>
Hello unexpected text!
~~~~~~~~~~~~~~~~~~~~~~~~
</Blah3>
!!! error TS2747: 'Blah3' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Cb | Cb[]'.
!!! related TS6500 tests/cases/compiler/index.tsx:54:3: The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & PropsMixed'
// Blah3 components don't accept multiple children of the wrong type.
var a = <Blah3>
{x => x}
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! related TS6502 tests/cases/compiler/index.tsx:52:11: The expected type comes from the return type of this signature.
{x => x}
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! related TS6502 tests/cases/compiler/index.tsx:52:11: The expected type comes from the return type of this signature.
</Blah3>

View file

@ -0,0 +1,119 @@
//// [index.tsx]
/// <reference path="/.lib/react16.d.ts" />
import * as React from "react";
interface Props {
children: (x: number) => string;
}
export function Blah(props: Props) {
return <></>;
}
// Incompatible child.
var a = <Blah>
{x => x}
</Blah>
// Blah components don't accept text as child elements
var a = <Blah>
Hello unexpected text!
</Blah>
// Blah components don't accept multiple children.
var a = <Blah>
{x => "" + x}
{x => "" + x}
</Blah>
interface PropsArr {
children: ((x: number) => string)[];
}
export function Blah2(props: PropsArr) {
return <></>;
}
// Incompatible child.
var a = <Blah2>
{x => x}
</Blah2>
// Blah2 components don't accept text as child elements
var a = <Blah2>
Hello unexpected text!
</Blah2>
// Blah2 components don't accept multiple children of the wrong type.
var a = <Blah2>
{x => x}
{x => x}
</Blah2>
type Cb = (x: number) => string;
interface PropsMixed {
children: Cb | Cb[];
}
export function Blah3(props: PropsMixed) {
return <></>;
}
// Incompatible child.
var a = <Blah3>
{x => x}
</Blah3>
// Blah3 components don't accept text as child elements
var a = <Blah3>
Hello unexpected text!
</Blah3>
// Blah3 components don't accept multiple children of the wrong type.
var a = <Blah3>
{x => x}
{x => x}
</Blah3>
//// [index.js]
"use strict";
exports.__esModule = true;
/// <reference path="react16.d.ts" />
var React = require("react");
function Blah(props) {
return React.createElement(React.Fragment, null);
}
exports.Blah = Blah;
// Incompatible child.
var a = React.createElement(Blah, null, function (x) { return x; });
// Blah components don't accept text as child elements
var a = React.createElement(Blah, null, "Hello unexpected text!");
// Blah components don't accept multiple children.
var a = React.createElement(Blah, null,
function (x) { return "" + x; },
function (x) { return "" + x; });
function Blah2(props) {
return React.createElement(React.Fragment, null);
}
exports.Blah2 = Blah2;
// Incompatible child.
var a = React.createElement(Blah2, null, function (x) { return x; });
// Blah2 components don't accept text as child elements
var a = React.createElement(Blah2, null, "Hello unexpected text!");
// Blah2 components don't accept multiple children of the wrong type.
var a = React.createElement(Blah2, null,
function (x) { return x; },
function (x) { return x; });
function Blah3(props) {
return React.createElement(React.Fragment, null);
}
exports.Blah3 = Blah3;
// Incompatible child.
var a = React.createElement(Blah3, null, function (x) { return x; });
// Blah3 components don't accept text as child elements
var a = React.createElement(Blah3, null, "Hello unexpected text!");
// Blah3 components don't accept multiple children of the wrong type.
var a = React.createElement(Blah3, null,
function (x) { return x; },
function (x) { return x; });

View file

@ -0,0 +1,169 @@
=== tests/cases/compiler/index.tsx ===
/// <reference path="react16.d.ts" />
import * as React from "react";
>React : Symbol(React, Decl(index.tsx, 1, 6))
interface Props {
>Props : Symbol(Props, Decl(index.tsx, 1, 31))
children: (x: number) => string;
>children : Symbol(Props.children, Decl(index.tsx, 3, 17))
>x : Symbol(x, Decl(index.tsx, 4, 13))
}
export function Blah(props: Props) {
>Blah : Symbol(Blah, Decl(index.tsx, 5, 1))
>props : Symbol(props, Decl(index.tsx, 7, 21))
>Props : Symbol(Props, Decl(index.tsx, 1, 31))
return <></>;
}
// Incompatible child.
var a = <Blah>
>a : Symbol(a, Decl(index.tsx, 12, 3), Decl(index.tsx, 17, 3), Decl(index.tsx, 22, 3), Decl(index.tsx, 36, 3), Decl(index.tsx, 41, 3) ... and 4 more)
>Blah : Symbol(Blah, Decl(index.tsx, 5, 1))
{x => x}
>x : Symbol(x, Decl(index.tsx, 13, 3))
>x : Symbol(x, Decl(index.tsx, 13, 3))
</Blah>
>Blah : Symbol(Blah, Decl(index.tsx, 5, 1))
// Blah components don't accept text as child elements
var a = <Blah>
>a : Symbol(a, Decl(index.tsx, 12, 3), Decl(index.tsx, 17, 3), Decl(index.tsx, 22, 3), Decl(index.tsx, 36, 3), Decl(index.tsx, 41, 3) ... and 4 more)
>Blah : Symbol(Blah, Decl(index.tsx, 5, 1))
Hello unexpected text!
</Blah>
>Blah : Symbol(Blah, Decl(index.tsx, 5, 1))
// Blah components don't accept multiple children.
var a = <Blah>
>a : Symbol(a, Decl(index.tsx, 12, 3), Decl(index.tsx, 17, 3), Decl(index.tsx, 22, 3), Decl(index.tsx, 36, 3), Decl(index.tsx, 41, 3) ... and 4 more)
>Blah : Symbol(Blah, Decl(index.tsx, 5, 1))
{x => "" + x}
>x : Symbol(x, Decl(index.tsx, 23, 3))
>x : Symbol(x, Decl(index.tsx, 23, 3))
{x => "" + x}
>x : Symbol(x, Decl(index.tsx, 24, 3))
>x : Symbol(x, Decl(index.tsx, 24, 3))
</Blah>
>Blah : Symbol(Blah, Decl(index.tsx, 5, 1))
interface PropsArr {
>PropsArr : Symbol(PropsArr, Decl(index.tsx, 25, 7))
children: ((x: number) => string)[];
>children : Symbol(PropsArr.children, Decl(index.tsx, 27, 20))
>x : Symbol(x, Decl(index.tsx, 28, 14))
}
export function Blah2(props: PropsArr) {
>Blah2 : Symbol(Blah2, Decl(index.tsx, 29, 1))
>props : Symbol(props, Decl(index.tsx, 31, 22))
>PropsArr : Symbol(PropsArr, Decl(index.tsx, 25, 7))
return <></>;
}
// Incompatible child.
var a = <Blah2>
>a : Symbol(a, Decl(index.tsx, 12, 3), Decl(index.tsx, 17, 3), Decl(index.tsx, 22, 3), Decl(index.tsx, 36, 3), Decl(index.tsx, 41, 3) ... and 4 more)
>Blah2 : Symbol(Blah2, Decl(index.tsx, 29, 1))
{x => x}
>x : Symbol(x, Decl(index.tsx, 37, 3))
>x : Symbol(x, Decl(index.tsx, 37, 3))
</Blah2>
>Blah2 : Symbol(Blah2, Decl(index.tsx, 29, 1))
// Blah2 components don't accept text as child elements
var a = <Blah2>
>a : Symbol(a, Decl(index.tsx, 12, 3), Decl(index.tsx, 17, 3), Decl(index.tsx, 22, 3), Decl(index.tsx, 36, 3), Decl(index.tsx, 41, 3) ... and 4 more)
>Blah2 : Symbol(Blah2, Decl(index.tsx, 29, 1))
Hello unexpected text!
</Blah2>
>Blah2 : Symbol(Blah2, Decl(index.tsx, 29, 1))
// Blah2 components don't accept multiple children of the wrong type.
var a = <Blah2>
>a : Symbol(a, Decl(index.tsx, 12, 3), Decl(index.tsx, 17, 3), Decl(index.tsx, 22, 3), Decl(index.tsx, 36, 3), Decl(index.tsx, 41, 3) ... and 4 more)
>Blah2 : Symbol(Blah2, Decl(index.tsx, 29, 1))
{x => x}
>x : Symbol(x, Decl(index.tsx, 47, 3))
>x : Symbol(x, Decl(index.tsx, 47, 3))
{x => x}
>x : Symbol(x, Decl(index.tsx, 48, 3))
>x : Symbol(x, Decl(index.tsx, 48, 3))
</Blah2>
>Blah2 : Symbol(Blah2, Decl(index.tsx, 29, 1))
type Cb = (x: number) => string;
>Cb : Symbol(Cb, Decl(index.tsx, 49, 8))
>x : Symbol(x, Decl(index.tsx, 51, 11))
interface PropsMixed {
>PropsMixed : Symbol(PropsMixed, Decl(index.tsx, 51, 32))
children: Cb | Cb[];
>children : Symbol(PropsMixed.children, Decl(index.tsx, 52, 22))
>Cb : Symbol(Cb, Decl(index.tsx, 49, 8))
>Cb : Symbol(Cb, Decl(index.tsx, 49, 8))
}
export function Blah3(props: PropsMixed) {
>Blah3 : Symbol(Blah3, Decl(index.tsx, 54, 1))
>props : Symbol(props, Decl(index.tsx, 56, 22))
>PropsMixed : Symbol(PropsMixed, Decl(index.tsx, 51, 32))
return <></>;
}
// Incompatible child.
var a = <Blah3>
>a : Symbol(a, Decl(index.tsx, 12, 3), Decl(index.tsx, 17, 3), Decl(index.tsx, 22, 3), Decl(index.tsx, 36, 3), Decl(index.tsx, 41, 3) ... and 4 more)
>Blah3 : Symbol(Blah3, Decl(index.tsx, 54, 1))
{x => x}
>x : Symbol(x, Decl(index.tsx, 62, 3))
>x : Symbol(x, Decl(index.tsx, 62, 3))
</Blah3>
>Blah3 : Symbol(Blah3, Decl(index.tsx, 54, 1))
// Blah3 components don't accept text as child elements
var a = <Blah3>
>a : Symbol(a, Decl(index.tsx, 12, 3), Decl(index.tsx, 17, 3), Decl(index.tsx, 22, 3), Decl(index.tsx, 36, 3), Decl(index.tsx, 41, 3) ... and 4 more)
>Blah3 : Symbol(Blah3, Decl(index.tsx, 54, 1))
Hello unexpected text!
</Blah3>
>Blah3 : Symbol(Blah3, Decl(index.tsx, 54, 1))
// Blah3 components don't accept multiple children of the wrong type.
var a = <Blah3>
>a : Symbol(a, Decl(index.tsx, 12, 3), Decl(index.tsx, 17, 3), Decl(index.tsx, 22, 3), Decl(index.tsx, 36, 3), Decl(index.tsx, 41, 3) ... and 4 more)
>Blah3 : Symbol(Blah3, Decl(index.tsx, 54, 1))
{x => x}
>x : Symbol(x, Decl(index.tsx, 72, 3))
>x : Symbol(x, Decl(index.tsx, 72, 3))
{x => x}
>x : Symbol(x, Decl(index.tsx, 73, 3))
>x : Symbol(x, Decl(index.tsx, 73, 3))
</Blah3>
>Blah3 : Symbol(Blah3, Decl(index.tsx, 54, 1))

View file

@ -0,0 +1,183 @@
=== tests/cases/compiler/index.tsx ===
/// <reference path="react16.d.ts" />
import * as React from "react";
>React : typeof React
interface Props {
children: (x: number) => string;
>children : (x: number) => string
>x : number
}
export function Blah(props: Props) {
>Blah : (props: Props) => JSX.Element
>props : Props
return <></>;
><></> : JSX.Element
}
// Incompatible child.
var a = <Blah>
>a : JSX.Element
><Blah> {x => x}</Blah> : JSX.Element
>Blah : (props: Props) => JSX.Element
{x => x}
>x => x : (x: number) => number
>x : number
>x : number
</Blah>
>Blah : (props: Props) => JSX.Element
// Blah components don't accept text as child elements
var a = <Blah>
>a : JSX.Element
><Blah> Hello unexpected text!</Blah> : JSX.Element
>Blah : (props: Props) => JSX.Element
Hello unexpected text!
</Blah>
>Blah : (props: Props) => JSX.Element
// Blah components don't accept multiple children.
var a = <Blah>
>a : JSX.Element
><Blah> {x => "" + x} {x => "" + x}</Blah> : JSX.Element
>Blah : (props: Props) => JSX.Element
{x => "" + x}
>x => "" + x : (x: number) => string
>x : number
>"" + x : string
>"" : ""
>x : number
{x => "" + x}
>x => "" + x : (x: number) => string
>x : number
>"" + x : string
>"" : ""
>x : number
</Blah>
>Blah : (props: Props) => JSX.Element
interface PropsArr {
children: ((x: number) => string)[];
>children : ((x: number) => string)[]
>x : number
}
export function Blah2(props: PropsArr) {
>Blah2 : (props: PropsArr) => JSX.Element
>props : PropsArr
return <></>;
><></> : JSX.Element
}
// Incompatible child.
var a = <Blah2>
>a : JSX.Element
><Blah2> {x => x}</Blah2> : JSX.Element
>Blah2 : (props: PropsArr) => JSX.Element
{x => x}
>x => x : (x: number) => number
>x : number
>x : number
</Blah2>
>Blah2 : (props: PropsArr) => JSX.Element
// Blah2 components don't accept text as child elements
var a = <Blah2>
>a : JSX.Element
><Blah2> Hello unexpected text!</Blah2> : JSX.Element
>Blah2 : (props: PropsArr) => JSX.Element
Hello unexpected text!
</Blah2>
>Blah2 : (props: PropsArr) => JSX.Element
// Blah2 components don't accept multiple children of the wrong type.
var a = <Blah2>
>a : JSX.Element
><Blah2> {x => x} {x => x}</Blah2> : JSX.Element
>Blah2 : (props: PropsArr) => JSX.Element
{x => x}
>x => x : (x: number) => number
>x : number
>x : number
{x => x}
>x => x : (x: number) => number
>x : number
>x : number
</Blah2>
>Blah2 : (props: PropsArr) => JSX.Element
type Cb = (x: number) => string;
>Cb : Cb
>x : number
interface PropsMixed {
children: Cb | Cb[];
>children : Cb | Cb[]
}
export function Blah3(props: PropsMixed) {
>Blah3 : (props: PropsMixed) => JSX.Element
>props : PropsMixed
return <></>;
><></> : JSX.Element
}
// Incompatible child.
var a = <Blah3>
>a : JSX.Element
><Blah3> {x => x}</Blah3> : JSX.Element
>Blah3 : (props: PropsMixed) => JSX.Element
{x => x}
>x => x : (x: number) => number
>x : number
>x : number
</Blah3>
>Blah3 : (props: PropsMixed) => JSX.Element
// Blah3 components don't accept text as child elements
var a = <Blah3>
>a : JSX.Element
><Blah3> Hello unexpected text!</Blah3> : JSX.Element
>Blah3 : (props: PropsMixed) => JSX.Element
Hello unexpected text!
</Blah3>
>Blah3 : (props: PropsMixed) => JSX.Element
// Blah3 components don't accept multiple children of the wrong type.
var a = <Blah3>
>a : JSX.Element
><Blah3> {x => x} {x => x}</Blah3> : JSX.Element
>Blah3 : (props: PropsMixed) => JSX.Element
{x => x}
>x => x : (x: number) => number
>x : number
>x : number
{x => x}
>x => x : (x: number) => number
>x : number
>x : number
</Blah3>
>Blah3 : (props: PropsMixed) => JSX.Element

View file

@ -0,0 +1,78 @@
// @jsx: react
// @strict: true
// @filename: index.tsx
/// <reference path="/.lib/react16.d.ts" />
import * as React from "react";
interface Props {
children: (x: number) => string;
}
export function Blah(props: Props) {
return <></>;
}
// Incompatible child.
var a = <Blah>
{x => x}
</Blah>
// Blah components don't accept text as child elements
var a = <Blah>
Hello unexpected text!
</Blah>
// Blah components don't accept multiple children.
var a = <Blah>
{x => "" + x}
{x => "" + x}
</Blah>
interface PropsArr {
children: ((x: number) => string)[];
}
export function Blah2(props: PropsArr) {
return <></>;
}
// Incompatible child.
var a = <Blah2>
{x => x}
</Blah2>
// Blah2 components don't accept text as child elements
var a = <Blah2>
Hello unexpected text!
</Blah2>
// Blah2 components don't accept multiple children of the wrong type.
var a = <Blah2>
{x => x}
{x => x}
</Blah2>
type Cb = (x: number) => string;
interface PropsMixed {
children: Cb | Cb[];
}
export function Blah3(props: PropsMixed) {
return <></>;
}
// Incompatible child.
var a = <Blah3>
{x => x}
</Blah3>
// Blah3 components don't accept text as child elements
var a = <Blah3>
Hello unexpected text!
</Blah3>
// Blah3 components don't accept multiple children of the wrong type.
var a = <Blah3>
{x => x}
{x => x}
</Blah3>