@@ -17189,31 +17189,14 @@ namespace ts {
17189
17189
const minLength = elementCount - (hasRestElement ? 1 : 0);
17190
17190
// If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
17191
17191
// that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
17192
+ let tupleResult: Type | undefined;
17192
17193
if (inDestructuringPattern && minLength > 0) {
17193
17194
const type = cloneTypeReference(<TypeReference>createTupleType(elementTypes, minLength, hasRestElement));
17194
17195
type.pattern = node;
17195
17196
return type;
17196
17197
}
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;
17217
17200
}
17218
17201
else if (forceTuple) {
17219
17202
return createTupleType(elementTypes, minLength, hasRestElement);
@@ -17222,6 +17205,31 @@ namespace ts {
17222
17205
return getArrayLiteralType(elementTypes, UnionReduction.Subtype);
17223
17206
}
17224
17207
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
+
17225
17233
function getArrayLiteralType(elementTypes: Type[], unionReduction = UnionReduction.Literal) {
17226
17234
return createArrayType(elementTypes.length ?
17227
17235
getUnionType(elementTypes, unionReduction) :
@@ -17637,11 +17645,13 @@ namespace ts {
17637
17645
error(attributes, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, unescapeLeadingUnderscores(jsxChildrenPropertyName));
17638
17646
}
17639
17647
17648
+ const contextualType = getApparentTypeOfContextualType(openingLikeElement.attributes);
17649
+ const childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName);
17640
17650
// 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
17641
17651
const childrenPropSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, jsxChildrenPropertyName);
17642
17652
childrenPropSymbol.type = childrenTypes.length === 1 ?
17643
17653
childrenTypes[0] :
17644
- createArrayType(getUnionType(childrenTypes));
17654
+ (getArrayLiteralTupleTypeIfApplicable(childrenTypes, childrenContextualType, /*hasRestElement*/ false) || createArrayType(getUnionType(childrenTypes) ));
17645
17655
const childPropMap = createSymbolTable();
17646
17656
childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
17647
17657
spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined),
0 commit comments