@@ -11870,7 +11870,7 @@ namespace ts {
11870
11870
* @param openingLikeElement a Jsx opening-like element
11871
11871
* @return an anonymous type (similar to the one returned by checkObjectLiteral) in which its properties are attributes property.
11872
11872
*/
11873
- function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, filter?:(symbol: Symbol)=> boolean) {
11873
+ function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, filter?: (symbol: Symbol) => boolean) {
11874
11874
const attributes = openingLikeElement.attributes;
11875
11875
let attributesTable = createMap<Symbol>();
11876
11876
let spread: Type = emptyObjectType;
@@ -11924,8 +11924,8 @@ namespace ts {
11924
11924
attributesTable = createMap<Symbol>();
11925
11925
if (attributesArray) {
11926
11926
forEach(attributesArray, (attr) => {
11927
- if (!filter || ( filter && filter (attr) )) {
11928
- attributesTable[ attr.name] = attr;
11927
+ if (!filter || filter(attr)) {
11928
+ attributesTable.set( attr.name, attr) ;
11929
11929
}
11930
11930
});
11931
11931
}
@@ -11963,7 +11963,7 @@ namespace ts {
11963
11963
*/
11964
11964
function checkJsxAttributesAssignableToTagnameAttributes(openingLikeElement: JsxOpeningLikeElement) {
11965
11965
// The function involves following steps:
11966
- // 1. Figure out expected attributes type expected by resolving tag-name of the JSX opening-like element, tagetAttributesType .
11966
+ // 1. Figure out expected attributes type expected by resolving tag-name of the JSX opening-like element, targetAttributesType .
11967
11967
// During these steps, we will try to resolve the tag-name as intrinsic name, stateless function, stateful component (in the order)
11968
11968
// 2. Solved Jsx attributes type given by users, sourceAttributesType, which is by resolving "attributes" property of the JSX opening-like element.
11969
11969
// 3. Check if the two are assignable to each other
@@ -11977,7 +11977,7 @@ namespace ts {
11977
11977
// i.e <div attr1={10} attr2="string" />
11978
11978
// attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes". They resolved to be sourceAttributesType.
11979
11979
const sourceAttributesType = createJsxAttributesTypeFromAttributesProperty(openingLikeElement,
11980
- ( attribute: Symbol) => {
11980
+ attribute => {
11981
11981
return isUnhyphenatedJsxName(attribute.name) || !!(getPropertyOfType(targetAttributesType, attribute.name));
11982
11982
});
11983
11983
@@ -13109,12 +13109,6 @@ namespace ts {
13109
13109
* @param excludeArgument
13110
13110
*/
13111
13111
function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map<RelationComparisonResult>) {
13112
- const headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
13113
- // Stateless function components can have maximum of three arguments: "props", "context", and "updater".
13114
- // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
13115
- // can be specified by users through attributes property.
13116
- const paramType = getTypeAtPosition(signature, 0);
13117
-
13118
13112
// JSX opening-like element has correct arity for stateless-function component if the one of the following condition is true:
13119
13113
// 1. callIsIncomplete
13120
13114
// 2. attributes property has same number of properties as the parameter object type.
@@ -13126,6 +13120,11 @@ namespace ts {
13126
13120
return true;
13127
13121
}
13128
13122
13123
+ const headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
13124
+ // Stateless function components can have maximum of three arguments: "props", "context", and "updater".
13125
+ // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
13126
+ // can be specified by users through attributes property.
13127
+ const paramType = getTypeAtPosition(signature, 0);
13129
13128
const argType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined);
13130
13129
const argProperties = getPropertiesOfType(argType);
13131
13130
const paramProperties = getPropertiesOfType(paramType);
@@ -13146,6 +13145,9 @@ namespace ts {
13146
13145
}
13147
13146
13148
13147
function checkApplicableSignature(node: CallLikeExpression, args: Expression[], signature: Signature, relation: Map<RelationComparisonResult>, excludeArgument: boolean[], reportErrors: boolean) {
13148
+ if (isJsxOpeningLikeElement(node)) {
13149
+ return checkApplicableSignatureForJsxOpeningLikeElement(<JsxOpeningLikeElement>node, signature, relation);
13150
+ }
13149
13151
const thisType = getThisTypeOfSignature(signature);
13150
13152
if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) {
13151
13153
// If the called expression is not of the form `x.f` or `x["f"]`, then sourceType = voidType
@@ -13620,12 +13622,10 @@ namespace ts {
13620
13622
return result;
13621
13623
}
13622
13624
13623
- // 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".
13624
13625
if (isJsxOpeningOrSelfClosingElement) {
13625
- // 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.
13626
- // (see getDefinitionAtPosition which simply get the symbol and return the first declaration of the JSXopeningLikeElement node)
13627
- // otherwise, just return the latest signature candidate we try so far so that when we report an error we will get better error message.
13628
- return produceDiagnostics ? candidateForArgumentError : undefined;
13626
+ // If there is not result, just return the last one we try as a candidate.
13627
+ // We do not report any error here because any error will be handled in "resolveCustomJsxElementAttributesType".
13628
+ return candidateForArgumentError;
13629
13629
}
13630
13630
13631
13631
// No signatures were applicable. Now report errors based on the last applicable signature with
@@ -13726,10 +13726,7 @@ namespace ts {
13726
13726
}
13727
13727
candidate = getSignatureInstantiation(candidate, typeArgumentTypes);
13728
13728
}
13729
- if (isJsxOpeningOrSelfClosingElement && !checkApplicableSignatureForJsxOpeningLikeElement(<JsxOpeningLikeElement>node, candidate, relation)) {
13730
- break;
13731
- }
13732
- else if (!isJsxOpeningOrSelfClosingElement && !checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
13729
+ if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
13733
13730
break;
13734
13731
}
13735
13732
const index = excludeArgument ? indexOf(excludeArgument, true) : -1;
@@ -14061,7 +14058,7 @@ namespace ts {
14061
14058
}
14062
14059
links.resolvedSignature = resolvingSignature;
14063
14060
14064
- let callSignature = resolvedStatelessJsxOpeningLikeElement (openingLikeElement, elementType, candidatesOutArray);
14061
+ let callSignature = resolveStatelessJsxOpeningLikeElement (openingLikeElement, elementType, candidatesOutArray);
14065
14062
if (!callSignature || callSignature === unknownSignature) {
14066
14063
const callSignatures = elementType && getSignaturesOfType(elementType, SignatureKind.Call);
14067
14064
callSignature = callSignatures[callSignatures.length - 1];
@@ -14083,14 +14080,14 @@ namespace ts {
14083
14080
* @return a resolved signature if we can find function matching function signature through resolve call or a first signature in the list of functions.
14084
14081
* otherwise return undefined if tag-name of the opening-like element doesn't have call signatures
14085
14082
*/
14086
- function resolvedStatelessJsxOpeningLikeElement (openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature {
14083
+ function resolveStatelessJsxOpeningLikeElement (openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature {
14087
14084
if (elementType.flags & TypeFlags.Union) {
14088
14085
const types = (elementType as UnionType).types;
14089
14086
let result: Signature;
14090
- types.map( type => {
14087
+ for (const type of types) {
14091
14088
// This is mainly to fill in all the candidates if there is one.
14092
- result = result || resolvedStatelessJsxOpeningLikeElement (openingLikeElement, type, candidatesOutArray);
14093
- });
14089
+ result = result || resolveStatelessJsxOpeningLikeElement (openingLikeElement, type, candidatesOutArray);
14090
+ }
14094
14091
14095
14092
return result;
14096
14093
}
@@ -14117,7 +14114,7 @@ namespace ts {
14117
14114
return resolveDecorator(<Decorator>node, candidatesOutArray);
14118
14115
case SyntaxKind.JsxOpeningElement:
14119
14116
case SyntaxKind.JsxSelfClosingElement:
14120
- return resolvedStatelessJsxOpeningLikeElement (<JsxOpeningLikeElement>node, checkExpression((<JsxOpeningLikeElement>node).tagName), candidatesOutArray);
14117
+ return resolveStatelessJsxOpeningLikeElement (<JsxOpeningLikeElement>node, checkExpression((<JsxOpeningLikeElement>node).tagName), candidatesOutArray);
14121
14118
}
14122
14119
Debug.fail("Branch in 'resolveSignature' should be unreachable.");
14123
14120
}
0 commit comments