diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 524b82c35b3..7771fa7e234 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -3359,8 +3359,8 @@ namespace ts {
return addOptionality(type, /*optional*/ declaration.questionToken && includeOptionality);
}
else if (isJsxAttribute(declaration)) {
- // For JSX Attribute, if it doesn't have initializer, by default the attribute gets true-type.
- // is sugar for
+ // if JSX attribute doesn't have initializer, by default the attribute will have boolean value of true.
+ // I.e is sugar for
return trueType;
}
@@ -6931,8 +6931,7 @@ namespace ts {
case SyntaxKind.JsxAttributes:
return forEach((node).properties, isContextSensitive);
case SyntaxKind.JsxAttribute:
- // If written as a shorthand (e.g <... attr /> then there is no explicit initializer as it has implicit boolean value of true
- // which is not context sensitvie.
+ // If there is no initializer, JSX attribute has a boolean value of true which is not context sensitive.
return (node).initializer && isContextSensitive((node).initializer);
case SyntaxKind.JsxExpression:
return isContextSensitive((node).expression);
@@ -7669,7 +7668,7 @@ namespace ts {
// reasoning about what went wrong.
Debug.assert(!!errorNode);
if (isJsxAttributes(errorNode)) {
- // JsxAttributes has an object-literal flag and is underwent same type-assignablity check as normal object-literal.
+ // JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal.
// However, using an object-literal error message will be very confusing to the users so we give different a message.
reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(target));
}
@@ -11316,9 +11315,9 @@ namespace ts {
}
function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute) {
- // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give JSXAttributes a contextual type
- // which is a type of the parameter of the signature we are trying out. This is not the case if it is a stateful JSX (i.e ReactComponenet class)
- // So if that is the case, just return the type of the JsxAttribute in such contextual type with out going into resolving of the JsxOpeningLikeElement again
+ // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
+ // which is a type of the parameter of the signature we are trying out.
+ // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName
const attributesType = getContextualType(attribute.parent) || getAttributesTypeFromJsxOpeningLikeElement(attribute.parent.parent);
if (isJsxAttribute(attribute)) {
@@ -11902,8 +11901,10 @@ namespace ts {
}
/**
- * Get attributes type of the given Jsx opening-like element. The result is from resolving "attributes" property of the opening-like element.
- * @param openingLikeElement a Jsx opening-like element
+ * Get attributes type of the JSX opening-like element. The result is from resolving "attributes" property of the opening-like element.
+ *
+ * @param openingLikeElement a JSX opening-like element
+ * @param filter a function to remove attributes that will not participate in checking whether attributes are assignable
* @return an anonymous type (similar to the one returned by checkObjectLiteral) in which its properties are attributes property.
*/
function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, filter?: (symbol: Symbol) => boolean, contextualMapper?: TypeMapper) {
@@ -11982,9 +11983,8 @@ namespace ts {
}
/**
- * Check JSXAttributes from "attributes" property. This function is used when we are trying to figure out call signature for JSX opening-like element during chooseOverload
- * In "checkApplicableSignatureForJsxOpeningLikeElement", we get type of arguments for potential stateless function by checking
- * the JSX opening-like element attributes property with contextual type.
+ * Check attributes property of opening-like element. This function is called during chooseOverload to get call signature of a JSX opening-like element.
+ * (See "checkApplicableSignatureForJsxOpeningLikeElement" for how the function is used)
* @param node a JSXAttributes to be resolved of its type
*/
function checkJsxAttributes(node: JsxAttributes, contextualMapper?: TypeMapper) {
@@ -11992,26 +11992,26 @@ namespace ts {
}
/**
- * Check whether the given attributes of JsxOpeningLikeElement is assignable to the tag-name attributes type.
- * Resolve the type of attributes of the openingLikeElement through checking type of tag-name
- * Check assignablity between given attributes property, "attributes" and the target attributes resulted from resolving tag-name
+ * Check whether the given attributes of JSX opening-like element is assignable to the tagName attributes.
+ * Get the attributes type of the opening-like element through resolving the tagName, "target attributes"
+ * Check assignablity between given attributes property, "source attributes", and the "target attributes"
* @param openingLikeElement an opening-like JSX element to check its JSXAttributes
*/
- function checkJsxAttributesAssignableToTagnameAttributes(openingLikeElement: JsxOpeningLikeElement) {
+ function checkJsxAttributesAssignableToTagNameAttributes(openingLikeElement: JsxOpeningLikeElement) {
// The function involves following steps:
- // 1. Figure out expected attributes type expected by resolving tag-name of the JSX opening-like element, targetAttributesType.
- // During these steps, we will try to resolve the tag-name as intrinsic name, stateless function, stateful component (in the order)
+ // 1. Figure out expected attributes type by resolving tagName of the JSX opening-like element, targetAttributesType.
+ // During these steps, we will try to resolve the tagName as intrinsic name, stateless function, stateful component (in the order)
// 2. Solved JSX attributes type given by users, sourceAttributesType, which is by resolving "attributes" property of the JSX opening-like element.
// 3. Check if the two are assignable to each other
- // targetAttributesType is a type of an attributes from resolving tag-name of an opening-like JSX element.
+ // targetAttributesType is a type of an attributes from resolving tagName of an opening-like JSX element.
const targetAttributesType = isJsxIntrinsicIdentifier(openingLikeElement.tagName) ?
getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement) :
getCustomJsxElementAttributesType(openingLikeElement, /*shouldIncludeAllStatelessAttributesType*/ false);
// sourceAttributesType is a type of an attributes properties.
// i.e
- // attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes". They resolved to be sourceAttributesType.
+ // attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes".
const sourceAttributesType = createJsxAttributesTypeFromAttributesProperty(openingLikeElement,
attribute => {
return isUnhyphenatedJsxName(attribute.name) || !!(getPropertyOfType(targetAttributesType, attribute.name));
@@ -12141,7 +12141,7 @@ namespace ts {
/**
* Get JSX attributes type by trying to resolve openingLikeElement as a stateless function component.
* Return only attributes type of successfully resolved call signature.
- * This function assumes that the caller handled other possible element type of the JSX element.
+ * This function assumes that the caller handled other possible element type of the JSX element (e.g. stateful component)
* Unlike tryGetAllJsxStatelessFunctionAttributesType, this function is a default behavior of type-checkers.
* @param openingLikeElement a JSX opening-like element to find attributes type
* @param elementType a type of the opening-like element. This elementType can't be an union type
@@ -12151,9 +12151,8 @@ namespace ts {
function defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement: JsxOpeningLikeElement, elementType: Type, elemInstanceType: Type, elementClassType?: Type): Type {
Debug.assert(!(elementType.flags & TypeFlags.Union));
if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) {
- // Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type
if (jsxElementType) {
- // We don't call getResolvedSignature because here we have already resolve the type of JSX Element.
+ // We don't call getResolvedSignature here because we have already resolve the type of JSX Element.
const callSignature = getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, /*candidatesOutArray*/ undefined);
const callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0]));
@@ -12175,7 +12174,6 @@ namespace ts {
* Return all attributes type of resolved call signature including candidate signatures.
* This function assumes that the caller handled other possible element type of the JSX element.
* This function is a behavior used by language service when looking up completion in JSX element.
- *
* @param openingLikeElement a JSX opening-like element to find attributes type
* @param elementType a type of the opening-like element. This elementType can't be an union type
* @param elemInstanceType an element instance type (the result of newing or invoking this tag)
@@ -12382,8 +12380,7 @@ namespace ts {
/**
* Get attributes type of the given custom opening-like JSX element.
- * The function is intended to be called from a function which has handle intrinsic JSX element already.
- *
+ * This function is intended to be called from a caller that handles intrinsic JSX element already.
* @param node a custom JSX opening-like element
*/
function getCustomJsxElementAttributesType(node: JsxOpeningLikeElement, shouldIncludeAllStatelessAttributesType: boolean): Type {
@@ -12396,12 +12393,8 @@ namespace ts {
}
/**
- * Get all possible attributes type, especially for an overload stateless function component, of the given JSX opening-like element.
- * This function is called by language service (see: completions-tryGetGlobalSymbols)
- *
- * Because in language service, the given JSX opening-like element may be incomplete and therefore, we can't resolve to exact signature if the element
- * is a stateless function component so the best thing to do is return all attributes type from all overloads.
- *
+ * Get all possible attributes type, especially from an overload stateless function component, of the given JSX opening-like element.
+ * This function is called by language service (see: completions-tryGetGlobalSymbols).
* @param node a JSX opening-like element to get attributes type for
*/
function getAllAttributesTypeFromJsxOpeningLikeElement(node: JsxOpeningLikeElement): Type {
@@ -12409,13 +12402,14 @@ namespace ts {
return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
}
else {
+ // Because in language service, the given JSX opening-like element may be incomplete and therefore,
+ // we can't resolve to exact signature if the element is a stateless function component so the best thing to do is return all attributes type from all overloads.
return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ true);
}
}
/**
* Get the attributes type which is the type that indicate which attributes are valid on the given JSXOpeningLikeElement.
- *
* @param node a JSXOpeningLikeElement node
* @return an attributes type of the given node
*/
@@ -12446,7 +12440,7 @@ namespace ts {
return jsxElementClassType;
}
- /// Returns all the properties of the Jsx.IntrinsicElements interface
+ // Returns all the properties of the Jsx.IntrinsicElements interface
function getJsxIntrinsicTagNames(): Symbol[] {
const intrinsics = getJsxType(JsxNames.IntrinsicElements);
return intrinsics ? getPropertiesOfType(intrinsics) : emptyArray;
@@ -12484,7 +12478,7 @@ namespace ts {
}
}
- checkJsxAttributesAssignableToTagnameAttributes(node);
+ checkJsxAttributesAssignableToTagNameAttributes(node);
}
function checkJsxExpression(node: JsxExpression, contextualMapper?: TypeMapper) {
@@ -13278,8 +13272,6 @@ namespace ts {
return undefined;
}
else if (isJsxOpeningLikeElement(node)) {
- // For a JSX opening-like element, even though we will recheck the attributes again in "checkApplicableSignatureForJsxOpeningLikeElement" to figure out correct arity.
- // We still return it here because when using infer type-argument we still have to getEffectiveArgument in trying to infer type-argument.
args = node.attributes.properties.length > 0 ? [node.attributes] : [];
}
else {
@@ -14087,11 +14079,10 @@ namespace ts {
}
/**
- * This function is similar to getResolvedSignature but exclusively for trying to resolve JSX stateless-function component.
- * The main reason we have to use this function because, the caller of this function will already check the type of openingLikeElement's tagname
- * pass the type as elementType. The elementType can not be a union (as such case should be handled by the caller of this function)
- * At this point, it is still not sure whether the opening-like element is a stateless function component or not.
- *
+ * This function is similar to getResolvedSignature but is exclusively for trying to resolve JSX stateless-function component.
+ * The main reason we have to use this function instead of getResolvedSignature because, the caller of this function will already check the type of openingLikeElement's tagName
+ * and pass the type as elementType. The elementType can not be a union (as such case should be handled by the caller of this function)
+ * Note: at this point, we are still not sure whether the opening-like element is a stateless function component or not.
* @param openingLikeElement an opening-like JSX element to try to resolve as JSX stateless function
* @param elementType an element type of the opneing-like element by checking opening-like element's tagname.
* @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service;
@@ -14120,8 +14111,8 @@ namespace ts {
}
/**
- * Try treating a given opening-like element as stateless function component and resolve a tag-name to a function signature.
- * @param openingLikeElement an JsxOpeningLikeElement we want to try resolve its state-less function if possible
+ * Try treating a given opening-like element as stateless function component and resolve a tagName to a function signature.
+ * @param openingLikeElement an JSX opening-like element we want to try resolve its stateless function if possible
* @param elementType a type of the opening-like JSX element, a result of resolving tagName in opening-like element.
* @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service;
* the function will fill it up with appropriate candidate signatures