mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-07 14:34:35 -06:00
Remove logic that pads array literals contextually typed by tuple types
This commit is contained in:
parent
2af8ac73ff
commit
2e5249835d
@ -722,6 +722,7 @@ namespace ts {
|
||||
NoIndexSignatures = 1 << 0,
|
||||
Writing = 1 << 1,
|
||||
CacheSymbol = 1 << 2,
|
||||
NoTupleBoundsCheck = 1 << 3,
|
||||
}
|
||||
|
||||
const enum CallbackCheck {
|
||||
@ -5115,21 +5116,25 @@ namespace ts {
|
||||
}
|
||||
else if (isArrayLikeType(parentType)) {
|
||||
const indexType = getLiteralType(index);
|
||||
const declaredType = getConstraintForLocation(getIndexedAccessType(parentType, indexType, declaration.name), declaration.name);
|
||||
const accessFlags = hasDefaultValue(declaration) ? AccessFlags.NoTupleBoundsCheck : 0;
|
||||
const declaredType = getConstraintForLocation(getIndexedAccessTypeOrUndefined(parentType, indexType, declaration.name, accessFlags) || errorType, declaration.name);
|
||||
type = getFlowTypeOfDestructuring(declaration, declaredType);
|
||||
}
|
||||
else {
|
||||
type = elementType;
|
||||
}
|
||||
}
|
||||
// In strict null checking mode, if a default value of a non-undefined type is specified, remove
|
||||
// undefined from the final type.
|
||||
if (strictNullChecks && declaration.initializer && !(getFalsyFlags(checkDeclarationInitializer(declaration)) & TypeFlags.Undefined)) {
|
||||
type = getTypeWithFacts(type, TypeFacts.NEUndefined);
|
||||
if (!declaration.initializer) {
|
||||
return type;
|
||||
}
|
||||
return declaration.initializer && !getEffectiveTypeAnnotationNode(walkUpBindingElementsAndPatterns(declaration)) ?
|
||||
getUnionType([type, checkDeclarationInitializer(declaration)], UnionReduction.Subtype) :
|
||||
type;
|
||||
if (getEffectiveTypeAnnotationNode(walkUpBindingElementsAndPatterns(declaration))) {
|
||||
// In strict null checking mode, if a default value of a non-undefined type is specified, remove
|
||||
// undefined from the final type.
|
||||
return strictNullChecks && !(getFalsyFlags(checkDeclarationInitializer(declaration)) & TypeFlags.Undefined) ?
|
||||
getTypeWithFacts(type, TypeFacts.NEUndefined) :
|
||||
type;
|
||||
}
|
||||
return getUnionType([getTypeWithFacts(type, TypeFacts.NEUndefined), checkDeclarationInitializer(declaration)], UnionReduction.Subtype);
|
||||
}
|
||||
|
||||
function getTypeForDeclarationFromJSDocComment(declaration: Node) {
|
||||
@ -10131,7 +10136,7 @@ namespace ts {
|
||||
propType;
|
||||
}
|
||||
if (everyType(objectType, isTupleType) && isNumericLiteralName(propName) && +propName >= 0) {
|
||||
if (accessNode && everyType(objectType, t => !(<TupleTypeReference>t).target.hasRestElement)) {
|
||||
if (accessNode && everyType(objectType, t => !(<TupleTypeReference>t).target.hasRestElement) && !(accessFlags & AccessFlags.NoTupleBoundsCheck)) {
|
||||
const indexNode = getIndexNodeForAccessExpression(accessNode);
|
||||
if (isTupleType(objectType)) {
|
||||
error(indexNode, Diagnostics.Tuple_type_0_of_length_1_has_no_element_at_index_2,
|
||||
@ -19196,26 +19201,7 @@ namespace ts {
|
||||
function getArrayLiteralTupleTypeIfApplicable(elementTypes: Type[], contextualType: Type | undefined, hasRestElement: boolean, elementCount = elementTypes.length, readonly = false) {
|
||||
// Infer a tuple type when the contextual type is or contains a tuple-like type
|
||||
if (readonly || (contextualType && forEachType(contextualType, isTupleLikeType))) {
|
||||
const minLength = elementCount - (hasRestElement ? 1 : 0);
|
||||
const pattern = contextualType && contextualType.pattern;
|
||||
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
|
||||
// tuple type with the corresponding binding or assignment element types to make the lengths equal.
|
||||
if (!hasRestElement && pattern && (pattern.kind === SyntaxKind.ArrayBindingPattern || pattern.kind === SyntaxKind.ArrayLiteralExpression)) {
|
||||
const patternElements = (<BindingPattern | ArrayLiteralExpression>pattern).elements;
|
||||
for (let i = elementCount; i < patternElements.length; i++) {
|
||||
const e = patternElements[i];
|
||||
if (hasDefaultValue(e)) {
|
||||
elementTypes.push((<TypeReference>contextualType).typeArguments![i]);
|
||||
}
|
||||
else if (i < patternElements.length - 1 || !(e.kind === SyntaxKind.BindingElement && (<BindingElement>e).dotDotDotToken || e.kind === SyntaxKind.SpreadElement)) {
|
||||
if (e.kind !== SyntaxKind.OmittedExpression) {
|
||||
error(e, Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
|
||||
}
|
||||
elementTypes.push(strictNullChecks ? implicitNeverType : undefinedWideningType);
|
||||
}
|
||||
}
|
||||
}
|
||||
return createTupleType(elementTypes, minLength, hasRestElement, readonly);
|
||||
return createTupleType(elementTypes, elementCount - (hasRestElement ? 1 : 0), hasRestElement, readonly);
|
||||
}
|
||||
}
|
||||
|
||||
@ -23655,8 +23641,10 @@ namespace ts {
|
||||
if (isArrayLikeType(sourceType)) {
|
||||
// We create a synthetic expression so that getIndexedAccessType doesn't get confused
|
||||
// when the element is a SyntaxKind.ElementAccessExpression.
|
||||
const elementType = getIndexedAccessType(sourceType, indexType, createSyntheticExpression(element, indexType));
|
||||
const type = getFlowTypeOfDestructuring(element, elementType);
|
||||
const accessFlags = hasDefaultValue(element) ? AccessFlags.NoTupleBoundsCheck : 0;
|
||||
const elementType = getIndexedAccessTypeOrUndefined(sourceType, indexType, createSyntheticExpression(element, indexType), accessFlags) || errorType;
|
||||
const assignedType = hasDefaultValue(element) ? getTypeWithFacts(elementType, TypeFacts.NEUndefined) : elementType;
|
||||
const type = getFlowTypeOfDestructuring(element, assignedType);
|
||||
return checkDestructuringAssignment(element, type, checkMode);
|
||||
}
|
||||
return checkDestructuringAssignment(element, elementType, checkMode);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user