diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 692b6ea848bf0..135c52eb50120 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -8797,18 +8797,20 @@ namespace ts {
if (!elemClassType || !isTypeAssignableTo(elemInstanceType, elemClassType)) {
// Is this is a stateless function component? See if its single signature's return type is
// assignable to the JSX Element Type
- const elemType = checkExpression(node.tagName);
- const callSignatures = elemType && getSignaturesOfType(elemType, SignatureKind.Call);
- const callSignature = callSignatures && callSignatures.length > 0 && callSignatures[0];
- const callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
- let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0]));
- if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) {
- // Intersect in JSX.IntrinsicAttributes if it exists
- const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
- if (intrinsicAttributes !== unknownType) {
- paramType = intersectTypes(intrinsicAttributes, paramType);
+ if (jsxElementType) {
+ const elemType = checkExpression(node.tagName);
+ const callSignatures = elemType && getSignaturesOfType(elemType, SignatureKind.Call);
+ const callSignature = callSignatures && callSignatures.length > 0 && callSignatures[0];
+ const callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
+ let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0]));
+ if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) {
+ // Intersect in JSX.IntrinsicAttributes if it exists
+ const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
+ if (intrinsicAttributes !== unknownType) {
+ paramType = intersectTypes(intrinsicAttributes, paramType);
+ }
+ return links.resolvedJsxType = paramType;
}
- return links.resolvedJsxType = paramType;
}
}
diff --git a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt
index b5d4e01b67782..32b86e455d22c 100644
--- a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt
+++ b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt
@@ -1,15 +1,18 @@
-tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx(13,15): error TS2322: Type '"f"' is not assignable to type '"A" | "B" | "C"'.
+tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx(16,15): error TS2322: Type '"f"' is not assignable to type '"A" | "B" | "C"'.
Type '"f"' is not assignable to type '"C"'.
-tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx(14,15): error TS2322: Type '"f"' is not assignable to type '"A" | "B" | "C"'.
+tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx(17,15): error TS2322: Type '"f"' is not assignable to type '"A" | "B" | "C"'.
Type '"f"' is not assignable to type '"C"'.
==== tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx (2 errors) ====
namespace JSX {
- interface IntrinsicElements {
+ export interface IntrinsicElements {
span: {};
}
+ export interface Element {
+ something?: any;
+ }
}
const FooComponent = (props: { foo: "A" | "B" | "C" }) => {props.foo};
diff --git a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.js b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.js
index c21247c283595..d1b2ebf5ae544 100644
--- a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.js
+++ b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.js
@@ -1,9 +1,12 @@
//// [contextuallyTypedStringLiteralsInJsxAttributes01.tsx]
namespace JSX {
- interface IntrinsicElements {
+ export interface IntrinsicElements {
span: {};
}
+ export interface Element {
+ something?: any;
+ }
}
const FooComponent = (props: { foo: "A" | "B" | "C" }) => {props.foo};
@@ -24,7 +27,13 @@ var FooComponent = function (props) { return {props.foo}; };
//// [contextuallyTypedStringLiteralsInJsxAttributes01.d.ts]
declare namespace JSX {
+ interface IntrinsicElements {
+ span: {};
+ }
+ interface Element {
+ something?: any;
+ }
}
declare const FooComponent: (props: {
foo: "A" | "B" | "C";
-}) => any;
+}) => JSX.Element;
diff --git a/tests/baselines/reference/tsxAttributeResolution13.js b/tests/baselines/reference/tsxAttributeResolution13.js
new file mode 100644
index 0000000000000..e6c942eb926c2
--- /dev/null
+++ b/tests/baselines/reference/tsxAttributeResolution13.js
@@ -0,0 +1,9 @@
+//// [test.tsx]
+
+function Test() { }
+
+
+
+//// [test.jsx]
+function Test() { }
+;
diff --git a/tests/baselines/reference/tsxAttributeResolution13.symbols b/tests/baselines/reference/tsxAttributeResolution13.symbols
new file mode 100644
index 0000000000000..a913e50969cc5
--- /dev/null
+++ b/tests/baselines/reference/tsxAttributeResolution13.symbols
@@ -0,0 +1,9 @@
+=== tests/cases/conformance/jsx/test.tsx ===
+
+function Test() { }
+>Test : Symbol(Test, Decl(test.tsx, 0, 0))
+
+
+>Test : Symbol(Test, Decl(test.tsx, 0, 0))
+>Test : Symbol(Test, Decl(test.tsx, 0, 0))
+
diff --git a/tests/baselines/reference/tsxAttributeResolution13.types b/tests/baselines/reference/tsxAttributeResolution13.types
new file mode 100644
index 0000000000000..f0435b8081265
--- /dev/null
+++ b/tests/baselines/reference/tsxAttributeResolution13.types
@@ -0,0 +1,10 @@
+=== tests/cases/conformance/jsx/test.tsx ===
+
+function Test() { }
+>Test : () => void
+
+
+> : any
+>Test : any
+>Test : any
+
diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution13.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution13.tsx
new file mode 100644
index 0000000000000..1b5937a7db232
--- /dev/null
+++ b/tests/cases/conformance/jsx/tsxAttributeResolution13.tsx
@@ -0,0 +1,5 @@
+//@jsx: preserve
+
+//@filename: test.tsx
+function Test() { }
+
diff --git a/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx b/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx
index ce6f4b7ac2f90..2235961086f7b 100644
--- a/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx
+++ b/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx
@@ -2,9 +2,12 @@
// @declaration: true
namespace JSX {
- interface IntrinsicElements {
+ export interface IntrinsicElements {
span: {};
}
+ export interface Element {
+ something?: any;
+ }
}
const FooComponent = (props: { foo: "A" | "B" | "C" }) => {props.foo};