@@ -17189,31 +17189,14 @@ namespace ts {
1718917189 const minLength = elementCount - (hasRestElement ? 1 : 0);
1719017190 // If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
1719117191 // that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
17192+ let tupleResult: Type | undefined;
1719217193 if (inDestructuringPattern && minLength > 0) {
1719317194 const type = cloneTypeReference(<TypeReference>createTupleType(elementTypes, minLength, hasRestElement));
1719417195 type.pattern = node;
1719517196 return type;
1719617197 }
17197- if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
17198- const pattern = contextualType.pattern;
17199- // If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
17200- // tuple type with the corresponding binding or assignment element types to make the lengths equal.
17201- if (!hasRestElement && pattern && (pattern.kind === SyntaxKind.ArrayBindingPattern || pattern.kind === SyntaxKind.ArrayLiteralExpression)) {
17202- const patternElements = (<BindingPattern | ArrayLiteralExpression>pattern).elements;
17203- for (let i = elementCount; i < patternElements.length; i++) {
17204- const e = patternElements[i];
17205- if (hasDefaultValue(e)) {
17206- elementTypes.push((<TypeReference>contextualType).typeArguments![i]);
17207- }
17208- else if (i < patternElements.length - 1 || !(e.kind === SyntaxKind.BindingElement && (<BindingElement>e).dotDotDotToken || e.kind === SyntaxKind.SpreadElement)) {
17209- if (e.kind !== SyntaxKind.OmittedExpression) {
17210- error(e, Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
17211- }
17212- elementTypes.push(strictNullChecks ? implicitNeverType : undefinedWideningType);
17213- }
17214- }
17215- }
17216- return createTupleType(elementTypes, minLength, hasRestElement);
17198+ else if (tupleResult = getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasRestElement, elementCount)) {
17199+ return tupleResult;
1721717200 }
1721817201 else if (forceTuple) {
1721917202 return createTupleType(elementTypes, minLength, hasRestElement);
@@ -17222,6 +17205,31 @@ namespace ts {
1722217205 return getArrayLiteralType(elementTypes, UnionReduction.Subtype);
1722317206 }
1722417207
17208+ function getArrayLiteralTupleTypeIfApplicable(elementTypes: Type[], contextualType: Type | undefined, hasRestElement: boolean, elementCount = elementTypes.length) {
17209+ if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
17210+ const minLength = elementCount - (hasRestElement ? 1 : 0);
17211+ const pattern = contextualType.pattern;
17212+ // If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
17213+ // tuple type with the corresponding binding or assignment element types to make the lengths equal.
17214+ if (!hasRestElement && pattern && (pattern.kind === SyntaxKind.ArrayBindingPattern || pattern.kind === SyntaxKind.ArrayLiteralExpression)) {
17215+ const patternElements = (<BindingPattern | ArrayLiteralExpression>pattern).elements;
17216+ for (let i = elementCount; i < patternElements.length; i++) {
17217+ const e = patternElements[i];
17218+ if (hasDefaultValue(e)) {
17219+ elementTypes.push((<TypeReference>contextualType).typeArguments![i]);
17220+ }
17221+ else if (i < patternElements.length - 1 || !(e.kind === SyntaxKind.BindingElement && (<BindingElement>e).dotDotDotToken || e.kind === SyntaxKind.SpreadElement)) {
17222+ if (e.kind !== SyntaxKind.OmittedExpression) {
17223+ error(e, Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
17224+ }
17225+ elementTypes.push(strictNullChecks ? implicitNeverType : undefinedWideningType);
17226+ }
17227+ }
17228+ }
17229+ return createTupleType(elementTypes, minLength, hasRestElement);
17230+ }
17231+ }
17232+
1722517233 function getArrayLiteralType(elementTypes: Type[], unionReduction = UnionReduction.Literal) {
1722617234 return createArrayType(elementTypes.length ?
1722717235 getUnionType(elementTypes, unionReduction) :
@@ -17637,11 +17645,13 @@ namespace ts {
1763717645 error(attributes, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, unescapeLeadingUnderscores(jsxChildrenPropertyName));
1763817646 }
1763917647
17648+ const contextualType = getApparentTypeOfContextualType(openingLikeElement.attributes);
17649+ const childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName);
1764017650 // If there are children in the body of JSX element, create dummy attribute "children" with the union of children types so that it will pass the attribute checking process
1764117651 const childrenPropSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, jsxChildrenPropertyName);
1764217652 childrenPropSymbol.type = childrenTypes.length === 1 ?
1764317653 childrenTypes[0] :
17644- createArrayType(getUnionType(childrenTypes));
17654+ (getArrayLiteralTupleTypeIfApplicable(childrenTypes, childrenContextualType, /*hasRestElement*/ false) || createArrayType(getUnionType(childrenTypes) ));
1764517655 const childPropMap = createSymbolTable();
1764617656 childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
1764717657 spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined),
0 commit comments