diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d1dbc966952..14d5254e1e9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7757,12 +7757,6 @@ namespace ts { let returnType = getUnionType(signatures.map(getReturnTypeOfSignature)); - // Issue an error if this return type isn't assignable to JSX.ElementClass - let elemClassType = getJsxGlobalElementClassType(); - if (elemClassType) { - checkTypeRelatedTo(returnType, elemClassType, assignableRelation, node, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements); - } - return returnType; } @@ -7813,8 +7807,27 @@ namespace ts { let sym = getJsxElementTagSymbol(node); if (links.jsxFlags & JsxFlags.ClassElement) { + // Get the element instance type (the result of newing or invoking this tag) let elemInstanceType = getJsxElementInstanceType(node); + // Is this is a stateless function component? See if its single signature is + // assignable to the JSX Element Type with either 0 arguments, or 1 argument + // that is an object type + let callSignature = getSingleCallSignature(getTypeOfSymbol(sym)); + let callReturnType = callSignature && getReturnTypeOfSignature(callSignature); + let paramType = callSignature && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0])); + if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType) && paramType.flags & TypeFlags.ObjectType) { + // TODO: Things like 'ref' and 'key' are always valid, how to account for that? + return paramType; + } + + // Issue an error if this return type isn't assignable to JSX.ElementClass + let elemClassType = getJsxGlobalElementClassType(); + if (elemClassType) { + checkTypeRelatedTo(elemInstanceType, elemClassType, assignableRelation, node, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements); + } + + if (isTypeAny(elemInstanceType)) { return links.resolvedJsxType = elemInstanceType; } diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt new file mode 100644 index 00000000000..343303f4b2c --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt @@ -0,0 +1,27 @@ +tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx(17,9): error TS2324: Property 'name' is missing in type '{ name: string; }'. +tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx(17,16): error TS2339: Property 'naaame' does not exist on type '{ name: string; }'. + + +==== tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx (2 errors) ==== + declare module JSX { + interface Element { el: any; } + interface IntrinsicElements { div: any; } + } + + + function Greet(x: {name: string}) { + return