Skip to content

Commit dbf5762

Browse files
committed
SFCs for JSX WIP
1 parent 16f69da commit dbf5762

4 files changed

Lines changed: 97 additions & 6 deletions

File tree

src/compiler/checker.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7757,12 +7757,6 @@ namespace ts {
77577757

77587758
let returnType = getUnionType(signatures.map(getReturnTypeOfSignature));
77597759

7760-
// Issue an error if this return type isn't assignable to JSX.ElementClass
7761-
let elemClassType = getJsxGlobalElementClassType();
7762-
if (elemClassType) {
7763-
checkTypeRelatedTo(returnType, elemClassType, assignableRelation, node, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements);
7764-
}
7765-
77667760
return returnType;
77677761
}
77687762

@@ -7813,8 +7807,27 @@ namespace ts {
78137807
let sym = getJsxElementTagSymbol(node);
78147808

78157809
if (links.jsxFlags & JsxFlags.ClassElement) {
7810+
// Get the element instance type (the result of newing or invoking this tag)
78167811
let elemInstanceType = getJsxElementInstanceType(node);
78177812

7813+
// Is this is a stateless function component? See if its single signature is
7814+
// assignable to the JSX Element Type with either 0 arguments, or 1 argument
7815+
// that is an object type
7816+
let callSignature = getSingleCallSignature(getTypeOfSymbol(sym));
7817+
let callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
7818+
let paramType = callSignature && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0]));
7819+
if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType) && paramType.flags & TypeFlags.ObjectType) {
7820+
// TODO: Things like 'ref' and 'key' are always valid, how to account for that?
7821+
return paramType;
7822+
}
7823+
7824+
// Issue an error if this return type isn't assignable to JSX.ElementClass
7825+
let elemClassType = getJsxGlobalElementClassType();
7826+
if (elemClassType) {
7827+
checkTypeRelatedTo(elemInstanceType, elemClassType, assignableRelation, node, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements);
7828+
}
7829+
7830+
78187831
if (isTypeAny(elemInstanceType)) {
78197832
return links.resolvedJsxType = elemInstanceType;
78207833
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx(17,9): error TS2324: Property 'name' is missing in type '{ name: string; }'.
2+
tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx(17,16): error TS2339: Property 'naaame' does not exist on type '{ name: string; }'.
3+
4+
5+
==== tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx (2 errors) ====
6+
declare module JSX {
7+
interface Element { el: any; }
8+
interface IntrinsicElements { div: any; }
9+
}
10+
11+
12+
function Greet(x: {name: string}) {
13+
return <div>Hello, {x}</div>;
14+
}
15+
function Meet({name = 'world'}) {
16+
return <div>Hello, {x}</div>;
17+
}
18+
19+
// OK
20+
let x = <Greet name='world' />;
21+
// Error
22+
let y = <Greet naaame='world' />;
23+
~~~~~~~~~~~~~~~~~~~~~~~~
24+
!!! error TS2324: Property 'name' is missing in type '{ name: string; }'.
25+
~~~~~~
26+
!!! error TS2339: Property 'naaame' does not exist on type '{ name: string; }'.
27+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//// [tsxStatelessFunctionComponents1.tsx]
2+
declare module JSX {
3+
interface Element { el: any; }
4+
interface IntrinsicElements { div: any; }
5+
}
6+
7+
8+
function Greet(x: {name: string}) {
9+
return <div>Hello, {x}</div>;
10+
}
11+
function Meet({name = 'world'}) {
12+
return <div>Hello, {x}</div>;
13+
}
14+
15+
// OK
16+
let x = <Greet name='world' />;
17+
// Error
18+
let y = <Greet naaame='world' />;
19+
20+
21+
//// [tsxStatelessFunctionComponents1.jsx]
22+
function Greet(x) {
23+
return <div>Hello, {x}</div>;
24+
}
25+
function Meet(_a) {
26+
var _b = _a.name, name = _b === void 0 ? 'world' : _b;
27+
return <div>Hello, {x}</div>;
28+
}
29+
// OK
30+
var x = <Greet name='world'/>;
31+
// Error
32+
var y = <Greet naaame='world'/>;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@filename: file.tsx
2+
//@jsx: preserve
3+
declare module JSX {
4+
interface Element { el: any; }
5+
interface IntrinsicElements { div: any; }
6+
}
7+
8+
9+
function Greet(x: {name: string}) {
10+
return <div>Hello, {x}</div>;
11+
}
12+
function Meet({name = 'world'}) {
13+
return <div>Hello, {x}</div>;
14+
}
15+
16+
// OK
17+
let x = <Greet name='world' />;
18+
// Error
19+
let y = <Greet naaame='world' />;

0 commit comments

Comments
 (0)