@@ -11197,11 +11197,8 @@ namespace ts {
11197
11197
if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) {
11198
11198
// Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type
11199
11199
if (jsxElementType) {
11200
- // Cached the result of trying to solve opening-like JSX element as a stateless function component (similar to how getResolvedSignature)
11201
- // We don't call getResolvedSignature directly because here we have already resolve the type of JSX Element.
11202
- const links = getNodeLinks(openingLikeElement);
11203
- const callSignature = resolvedStateLessJsxOpeningLikeElement(openingLikeElement, elementType, /*candidatesOutArray*/ undefined);
11204
- links.resolvedSignature = callSignature;
11200
+ // We don't call getResolvedSignature because here we have already resolve the type of JSX Element.
11201
+ const callSignature = getResolvedJSXStatelessFunctionSignature(openingLikeElement, elementType, /*candidatesOutArray*/ undefined);
11205
11202
const callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
11206
11203
let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0]));
11207
11204
if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) {
@@ -11232,12 +11229,9 @@ namespace ts {
11232
11229
if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) {
11233
11230
// Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type
11234
11231
if (jsxElementType) {
11235
- // Cached the result of trying to solve opening-like JSX element as a stateless function component (similar to how getResolvedSignature)
11236
- // We don't call getResolvedSignature directly because here we have already resolve the type of JSX Element.
11237
- const links = getNodeLinks(openingLikeElement);
11232
+ // We don't call getResolvedSignature because here we have already resolve the type of JSX Element.
11238
11233
const candidatesOutArray: Signature[] = [];
11239
- const callSignature = resolvedStateLessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray);
11240
- links.resolvedSignature = callSignature;
11234
+ getResolvedJSXStatelessFunctionSignature(openingLikeElement, elementType, candidatesOutArray);
11241
11235
let result: Type;
11242
11236
let defaultResult: Type;
11243
11237
for (const candidate of candidatesOutArray) {
@@ -12760,9 +12754,11 @@ namespace ts {
12760
12754
}
12761
12755
12762
12756
// Do not report any error if we are doing so for stateless function component as such error will be error will be handle in "resolveCustomJsxElementAttributesType".
12763
- // Just return the latest signature candidate we try so far so that when we report an error we will get better error message.
12764
12757
if (isJsxOpeningOrSelfClosingElement) {
12765
- return candidateForArgumentError;
12758
+ // If this is a type resolution session, e.g. Language Service, just return undefined as the language service can decide how to proceed with this failure.
12759
+ // (see getDefinitionAtPosition which simply get the symbol and return the first declaration of the JSXopeningLikeElement node)
12760
+ // otherwise, just return the latest signature candidate we try so far so that when we report an error we will get better error message.
12761
+ return produceDiagnostics ? candidateForArgumentError : undefined;
12766
12762
}
12767
12763
12768
12764
// No signatures were applicable. Now report errors based on the last applicable signature with
@@ -13178,6 +13174,38 @@ namespace ts {
13178
13174
return resolveCall(node, callSignatures, candidatesOutArray, headMessage);
13179
13175
}
13180
13176
13177
+ /**
13178
+ *
13179
+ * @param openingLikeElement
13180
+ * @param elementType
13181
+ * @param candidatesOutArray
13182
+ */
13183
+ function getResolvedJSXStatelessFunctionSignature(openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature {
13184
+ Debug.assert(!(elementType.flags & TypeFlags.Union));
13185
+ const links = getNodeLinks(openingLikeElement);
13186
+ // If getResolvedSignature has already been called, we will have cached the resolvedSignature.
13187
+ // However, it is possible that either candidatesOutArray was not passed in the first time,
13188
+ // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work
13189
+ // to correctly fill the candidatesOutArray.
13190
+ const cached = links.resolvedSignature;
13191
+ if (cached && cached !== resolvingSignature && !candidatesOutArray) {
13192
+ return cached;
13193
+ }
13194
+ links.resolvedSignature = resolvingSignature;
13195
+
13196
+ let callSignature = resolvedStateLessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray);
13197
+ if (!callSignature || callSignature === unknownSignature) {
13198
+ const callSignatures = elementType && getSignaturesOfType(elementType, SignatureKind.Call);
13199
+ callSignature = callSignatures[callSignatures.length - 1];
13200
+ }
13201
+ links.resolvedSignature = callSignature;
13202
+ // If signature resolution originated in control flow type analysis (for example to compute the
13203
+ // assigned type in a flow assignment) we don't cache the result as it may be based on temporary
13204
+ // types from the control flow analysis.
13205
+ links.resolvedSignature = flowLoopStart === flowLoopCount ? callSignature : cached;
13206
+ return callSignature;
13207
+ }
13208
+
13181
13209
/**
13182
13210
* Try treating a given opening-like element as stateless function component and try to resolve a signature.
13183
13211
* @param openingLikeElement an JsxOpeningLikeElement we want to try resolve its state-less function if possible
@@ -13187,7 +13215,7 @@ namespace ts {
13187
13215
* @return a resolved signature if we can find function matching function signature through resolve call or a first signature in the list of functions.
13188
13216
* otherwise return undefined if tag-name of the opening-like element doesn't have call signatures
13189
13217
*/
13190
- function resolvedStateLessJsxOpeningLikeElement(openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature | undefined {
13218
+ function resolvedStateLessJsxOpeningLikeElement(openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature {
13191
13219
if (elementType.flags & TypeFlags.Union) {
13192
13220
const types = (elementType as UnionType).types;
13193
13221
let result: Signature;
@@ -13202,7 +13230,7 @@ namespace ts {
13202
13230
const callSignatures = elementType && getSignaturesOfType(elementType, SignatureKind.Call);
13203
13231
if (callSignatures && callSignatures.length > 0) {
13204
13232
let callSignature: Signature;
13205
- callSignature = resolveCall(openingLikeElement, callSignatures, candidatesOutArray) || callSignatures[0] ;
13233
+ callSignature = resolveCall(openingLikeElement, callSignatures, candidatesOutArray);
13206
13234
return callSignature;
13207
13235
}
13208
13236
0 commit comments