mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #7308 from RyanCavanaugh/fix7286
Don't crash if there's no JSX.Element during SFC resolution
This commit is contained in:
+13
-11
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -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" }) => <span>{props.foo}</span>;
|
||||
|
||||
@@ -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" }) => <span>{props.foo}</span>;
|
||||
@@ -24,7 +27,13 @@ var FooComponent = function (props) { return <span>{props.foo}</span>; };
|
||||
|
||||
//// [contextuallyTypedStringLiteralsInJsxAttributes01.d.ts]
|
||||
declare namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
span: {};
|
||||
}
|
||||
interface Element {
|
||||
something?: any;
|
||||
}
|
||||
}
|
||||
declare const FooComponent: (props: {
|
||||
foo: "A" | "B" | "C";
|
||||
}) => any;
|
||||
}) => JSX.Element;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
//// [test.tsx]
|
||||
|
||||
function Test() { }
|
||||
<Test></Test>
|
||||
|
||||
|
||||
//// [test.jsx]
|
||||
function Test() { }
|
||||
<Test></Test>;
|
||||
@@ -0,0 +1,9 @@
|
||||
=== tests/cases/conformance/jsx/test.tsx ===
|
||||
|
||||
function Test() { }
|
||||
>Test : Symbol(Test, Decl(test.tsx, 0, 0))
|
||||
|
||||
<Test></Test>
|
||||
>Test : Symbol(Test, Decl(test.tsx, 0, 0))
|
||||
>Test : Symbol(Test, Decl(test.tsx, 0, 0))
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
=== tests/cases/conformance/jsx/test.tsx ===
|
||||
|
||||
function Test() { }
|
||||
>Test : () => void
|
||||
|
||||
<Test></Test>
|
||||
><Test></Test> : any
|
||||
>Test : any
|
||||
>Test : any
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
//@jsx: preserve
|
||||
|
||||
//@filename: test.tsx
|
||||
function Test() { }
|
||||
<Test></Test>
|
||||
+4
-1
@@ -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" }) => <span>{props.foo}</span>;
|
||||
|
||||
Reference in New Issue
Block a user