@@ -83,6 +83,7 @@ namespace ts {
8383 getSymbolsInScope,
8484 getSymbolAtLocation,
8585 getShorthandAssignmentValueSymbol,
86+ getExportSpecifierLocalTargetSymbol,
8687 getTypeAtLocation: getTypeOfNode,
8788 typeToString,
8889 getSymbolDisplayBuilder,
@@ -8176,27 +8177,31 @@ namespace ts {
81768177 // Get the element instance type (the result of newing or invoking this tag)
81778178 const elemInstanceType = getJsxElementInstanceType(node);
81788179
8179- // Is this is a stateless function component? See if its single signature is
8180- // assignable to the JSX Element Type
8181- const callSignature = getSingleCallSignature(getTypeOfSymbol(sym));
8182- const callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
8183- let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0]));
8184- if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType) && (paramType.flags & TypeFlags.ObjectType)) {
8185- // Intersect in JSX.IntrinsicAttributes if it exists
8186- const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
8187- if (intrinsicAttributes !== unknownType) {
8188- paramType = intersectTypes(intrinsicAttributes, paramType);
8180+ const elemClassType = getJsxGlobalElementClassType();
8181+
8182+ if (!elemClassType || !isTypeAssignableTo(elemInstanceType, elemClassType)) {
8183+ // Is this is a stateless function component? See if its single signature's return type is
8184+ // assignable to the JSX Element Type
8185+ const elemType = getTypeOfSymbol(sym);
8186+ const callSignatures = elemType && getSignaturesOfType(elemType, SignatureKind.Call);
8187+ const callSignature = callSignatures && callSignatures.length > 0 && callSignatures[0];
8188+ const callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
8189+ let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0]));
8190+ if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) {
8191+ // Intersect in JSX.IntrinsicAttributes if it exists
8192+ const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
8193+ if (intrinsicAttributes !== unknownType) {
8194+ paramType = intersectTypes(intrinsicAttributes, paramType);
8195+ }
8196+ return links.resolvedJsxType = paramType;
81898197 }
8190- return paramType;
81918198 }
81928199
81938200 // Issue an error if this return type isn't assignable to JSX.ElementClass
8194- const elemClassType = getJsxGlobalElementClassType();
81958201 if (elemClassType) {
81968202 checkTypeRelatedTo(elemInstanceType, elemClassType, assignableRelation, node, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements);
81978203 }
81988204
8199-
82008205 if (isTypeAny(elemInstanceType)) {
82018206 return links.resolvedJsxType = elemInstanceType;
82028207 }
@@ -11128,7 +11133,53 @@ namespace ts {
1112811133 return -1;
1112911134 }
1113011135
11131- function isInLegalParameterTypePredicatePosition(node: Node): boolean {
11136+ function checkTypePredicate(node: TypePredicateNode) {
11137+ const parent = getTypePredicateParent(node);
11138+ if (!parent) {
11139+ return;
11140+ }
11141+ const returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(parent));
11142+ if (!returnType || !(returnType.flags & TypeFlags.PredicateType)) {
11143+ return;
11144+ }
11145+ const { parameterName } = node;
11146+ if (parameterName.kind === SyntaxKind.ThisType) {
11147+ getTypeFromThisTypeNode(parameterName as ThisTypeNode);
11148+ }
11149+ else {
11150+ const typePredicate = <IdentifierTypePredicate>(<PredicateType>returnType).predicate;
11151+ if (typePredicate.parameterIndex >= 0) {
11152+ if (parent.parameters[typePredicate.parameterIndex].dotDotDotToken) {
11153+ error(parameterName,
11154+ Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
11155+ }
11156+ else {
11157+ checkTypeAssignableTo(typePredicate.type,
11158+ getTypeOfNode(parent.parameters[typePredicate.parameterIndex]),
11159+ node.type);
11160+ }
11161+ }
11162+ else if (parameterName) {
11163+ let hasReportedError = false;
11164+ for (const { name } of parent.parameters) {
11165+ if ((name.kind === SyntaxKind.ObjectBindingPattern ||
11166+ name.kind === SyntaxKind.ArrayBindingPattern) &&
11167+ checkIfTypePredicateVariableIsDeclaredInBindingPattern(
11168+ <BindingPattern>name,
11169+ parameterName,
11170+ typePredicate.parameterName)) {
11171+ hasReportedError = true;
11172+ break;
11173+ }
11174+ }
11175+ if (!hasReportedError) {
11176+ error(node.parameterName, Diagnostics.Cannot_find_parameter_0, typePredicate.parameterName);
11177+ }
11178+ }
11179+ }
11180+ }
11181+
11182+ function getTypePredicateParent(node: Node): SignatureDeclaration {
1113211183 switch (node.parent.kind) {
1113311184 case SyntaxKind.ArrowFunction:
1113411185 case SyntaxKind.CallSignature:
@@ -11137,22 +11188,35 @@ namespace ts {
1113711188 case SyntaxKind.FunctionType:
1113811189 case SyntaxKind.MethodDeclaration:
1113911190 case SyntaxKind.MethodSignature:
11140- return node === (<SignatureDeclaration>node.parent).type;
11191+ const parent = <SignatureDeclaration>node.parent;
11192+ if (node === parent.type) {
11193+ return parent;
11194+ }
1114111195 }
11142- return false;
1114311196 }
1114411197
11145- function isInLegalThisTypePredicatePosition(node: Node): boolean {
11146- if (isInLegalParameterTypePredicatePosition(node)) {
11147- return true;
11148- }
11149- switch (node.parent.kind) {
11150- case SyntaxKind.PropertyDeclaration:
11151- case SyntaxKind.PropertySignature:
11152- case SyntaxKind.GetAccessor:
11153- return node === (node.parent as (PropertyDeclaration | GetAccessorDeclaration | PropertySignature)).type;
11198+ function checkIfTypePredicateVariableIsDeclaredInBindingPattern(
11199+ pattern: BindingPattern,
11200+ predicateVariableNode: Node,
11201+ predicateVariableName: string) {
11202+ for (const { name } of pattern.elements) {
11203+ if (name.kind === SyntaxKind.Identifier &&
11204+ (<Identifier>name).text === predicateVariableName) {
11205+ error(predicateVariableNode,
11206+ Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern,
11207+ predicateVariableName);
11208+ return true;
11209+ }
11210+ else if (name.kind === SyntaxKind.ArrayBindingPattern ||
11211+ name.kind === SyntaxKind.ObjectBindingPattern) {
11212+ if (checkIfTypePredicateVariableIsDeclaredInBindingPattern(
11213+ <BindingPattern>name,
11214+ predicateVariableNode,
11215+ predicateVariableName)) {
11216+ return true;
11217+ }
11218+ }
1115411219 }
11155- return false;
1115611220 }
1115711221
1115811222 function checkSignatureDeclaration(node: SignatureDeclaration) {
@@ -11171,68 +11235,8 @@ namespace ts {
1117111235
1117211236 forEach(node.parameters, checkParameter);
1117311237
11174- if (node.type) {
11175- if (node.type.kind === SyntaxKind.TypePredicate) {
11176- const returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(node));
11177- if (!returnType || !(returnType.flags & TypeFlags.PredicateType)) {
11178- return;
11179- }
11180- const typePredicate = (returnType as PredicateType).predicate;
11181- const typePredicateNode = node.type as TypePredicateNode;
11182- checkSourceElement(typePredicateNode);
11183- if (isIdentifierTypePredicate(typePredicate)) {
11184- if (typePredicate.parameterIndex >= 0) {
11185- if (node.parameters[typePredicate.parameterIndex].dotDotDotToken) {
11186- error(typePredicateNode.parameterName,
11187- Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
11188- }
11189- else {
11190- checkTypeAssignableTo(typePredicate.type,
11191- getTypeOfNode(node.parameters[typePredicate.parameterIndex]),
11192- typePredicateNode.type);
11193- }
11194- }
11195- else if (typePredicateNode.parameterName) {
11196- let hasReportedError = false;
11197- for (var param of node.parameters) {
11198- if (hasReportedError) {
11199- break;
11200- }
11201- if (param.name.kind === SyntaxKind.ObjectBindingPattern ||
11202- param.name.kind === SyntaxKind.ArrayBindingPattern) {
11203-
11204- (function checkBindingPattern(pattern: BindingPattern) {
11205- for (const element of pattern.elements) {
11206- if (element.name.kind === SyntaxKind.Identifier &&
11207- (<Identifier>element.name).text === typePredicate.parameterName) {
11208-
11209- error(typePredicateNode.parameterName,
11210- Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern,
11211- typePredicate.parameterName);
11212- hasReportedError = true;
11213- break;
11214- }
11215- else if (element.name.kind === SyntaxKind.ArrayBindingPattern ||
11216- element.name.kind === SyntaxKind.ObjectBindingPattern) {
11217-
11218- checkBindingPattern(<BindingPattern>element.name);
11219- }
11220- }
11221- })(<BindingPattern>param.name);
11222- }
11223- }
11224- if (!hasReportedError) {
11225- error(typePredicateNode.parameterName,
11226- Diagnostics.Cannot_find_parameter_0,
11227- typePredicate.parameterName);
11228- }
11229- }
11230- }
11231- }
11232- else {
11233- checkSourceElement(node.type);
11234- }
11235- }
11238+ checkSourceElement(node.type);
11239+
1123611240
1123711241 if (produceDiagnostics) {
1123811242 checkCollisionWithArgumentsInGeneratedCode(node);
@@ -14401,20 +14405,6 @@ namespace ts {
1440114405 }
1440214406 }
1440314407
14404- function checkTypePredicate(node: TypePredicateNode) {
14405- const { parameterName } = node;
14406- if (parameterName.kind === SyntaxKind.Identifier && !isInLegalParameterTypePredicatePosition(node)) {
14407- error(node, Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
14408- }
14409- else if (parameterName.kind === SyntaxKind.ThisType) {
14410- if (!isInLegalThisTypePredicatePosition(node)) {
14411- error(node, Diagnostics.A_this_based_type_predicate_is_only_allowed_within_a_class_or_interface_s_members_get_accessors_or_return_type_positions_for_functions_and_methods);
14412- }
14413- else {
14414- getTypeFromThisTypeNode(parameterName as ThisTypeNode);
14415- }
14416- }
14417- }
1441814408
1441914409 function checkSourceElement(node: Node): void {
1442014410 if (!node) {
@@ -15018,11 +15008,18 @@ namespace ts {
1501815008 // This is necessary as an identifier in short-hand property assignment can contains two meaning:
1501915009 // property name and property value.
1502015010 if (location && location.kind === SyntaxKind.ShorthandPropertyAssignment) {
15021- return resolveEntityName((<ShorthandPropertyAssignment>location).name, SymbolFlags.Value);
15011+ return resolveEntityName((<ShorthandPropertyAssignment>location).name, SymbolFlags.Value | SymbolFlags.Alias );
1502215012 }
1502315013 return undefined;
1502415014 }
1502515015
15016+ /** Returns the target of an export specifier without following aliases */
15017+ function getExportSpecifierLocalTargetSymbol(node: ExportSpecifier): Symbol {
15018+ return (<ExportDeclaration>node.parent.parent).moduleSpecifier ?
15019+ getExternalModuleMember(<ExportDeclaration>node.parent.parent, node) :
15020+ resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias);
15021+ }
15022+
1502615023 function getTypeOfNode(node: Node): Type {
1502715024 if (isInsideWithStatementBody(node)) {
1502815025 // We cannot answer semantic questions within a with block, do not proceed any further
0 commit comments