SFCs for JSX WIP

This commit is contained in:
Ryan Cavanaugh 2015-11-03 13:05:11 -08:00
parent 16f69daf10
commit dbf5762156
4 changed files with 97 additions and 6 deletions

View File

@ -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;
}

View File

@ -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 <div>Hello, {x}</div>;
}
function Meet({name = 'world'}) {
return <div>Hello, {x}</div>;
}
// OK
let x = <Greet name='world' />;
// Error
let y = <Greet naaame='world' />;
~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2324: Property 'name' is missing in type '{ name: string; }'.
~~~~~~
!!! error TS2339: Property 'naaame' does not exist on type '{ name: string; }'.

View File

@ -0,0 +1,32 @@
//// [tsxStatelessFunctionComponents1.tsx]
declare module JSX {
interface Element { el: any; }
interface IntrinsicElements { div: any; }
}
function Greet(x: {name: string}) {
return <div>Hello, {x}</div>;
}
function Meet({name = 'world'}) {
return <div>Hello, {x}</div>;
}
// OK
let x = <Greet name='world' />;
// Error
let y = <Greet naaame='world' />;
//// [tsxStatelessFunctionComponents1.jsx]
function Greet(x) {
return <div>Hello, {x}</div>;
}
function Meet(_a) {
var _b = _a.name, name = _b === void 0 ? 'world' : _b;
return <div>Hello, {x}</div>;
}
// OK
var x = <Greet name='world'/>;
// Error
var y = <Greet naaame='world'/>;

View File

@ -0,0 +1,19 @@
//@filename: file.tsx
//@jsx: preserve
declare module JSX {
interface Element { el: any; }
interface IntrinsicElements { div: any; }
}
function Greet(x: {name: string}) {
return <div>Hello, {x}</div>;
}
function Meet({name = 'world'}) {
return <div>Hello, {x}</div>;
}
// OK
let x = <Greet name='world' />;
// Error
let y = <Greet naaame='world' />;