Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18565,7 +18565,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
if (everyType(objectType, isTupleType) && isNumericLiteralName(propName)) {
const index = +propName;
if (accessNode && everyType(objectType, t => !(t as TupleTypeReference).target.hasRestElement) && !(accessFlags & AccessFlags.NoTupleBoundsCheck)) {
if (accessNode && everyType(objectType, t => !((t as TupleTypeReference).target.combinedFlags & ElementFlags.Variable)) && !(accessFlags & AccessFlags.NoTupleBoundsCheck)) {
const indexNode = getIndexNodeForAccessExpression(accessNode);
if (isTupleType(objectType)) {
if (index < 0) {
Expand Down Expand Up @@ -25753,7 +25753,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

function tupleTypesDefinitelyUnrelated(source: TupleTypeReference, target: TupleTypeReference) {
return !(target.target.combinedFlags & ElementFlags.Variadic) && target.target.minLength > source.target.minLength ||
!target.target.hasRestElement && (source.target.hasRestElement || target.target.fixedLength < source.target.fixedLength);
!(target.target.combinedFlags & ElementFlags.Variable) && (!!(source.target.combinedFlags & ElementFlags.Variable) || target.target.fixedLength < source.target.fixedLength);
}

function typesDefinitelyUnrelated(source: Type, target: Type) {
Expand Down Expand Up @@ -26584,7 +26584,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return;
}
const startLength = isTupleType(source) ? Math.min(source.target.fixedLength, target.target.fixedLength) : 0;
const endLength = Math.min(isTupleType(source) ? getEndElementCount(source.target, ElementFlags.Fixed) : 0, target.target.hasRestElement ? getEndElementCount(target.target, ElementFlags.Fixed) : 0);
const endLength = Math.min(isTupleType(source) ? getEndElementCount(source.target, ElementFlags.Fixed) : 0, target.target.combinedFlags & ElementFlags.Variable ? getEndElementCount(target.target, ElementFlags.Fixed) : 0);
// Infer between starting fixed elements.
for (let i = 0; i < startLength; i++) {
inferFromTypes(getTypeArguments(source)[i], elementTypes[i]);
Expand Down Expand Up @@ -26613,7 +26613,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// if T is constrained by a fixed-size tuple we might be able to use its arity to infer T
const param = getInferenceInfoForType(elementTypes[startLength])?.typeParameter;
const constraint = param && getBaseConstraintOfType(param);
if (constraint && isTupleType(constraint) && !constraint.target.hasRestElement) {
if (constraint && isTupleType(constraint) && !(constraint.target.combinedFlags & ElementFlags.Variable)) {
const impliedArity = constraint.target.fixedLength;
inferFromTypes(sliceTupleType(source, startLength, sourceArity - (startLength + impliedArity)), elementTypes[startLength]);
inferFromTypes(getElementTypeOfSliceOfTupleType(source, startLength + impliedArity, endLength)!, elementTypes[startLength + 1]);
Expand All @@ -26624,7 +26624,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// if T is constrained by a fixed-size tuple we might be able to use its arity to infer T
const param = getInferenceInfoForType(elementTypes[startLength + 1])?.typeParameter;
const constraint = param && getBaseConstraintOfType(param);
if (constraint && isTupleType(constraint) && !constraint.target.hasRestElement) {
if (constraint && isTupleType(constraint) && !(constraint.target.combinedFlags & ElementFlags.Variable)) {
const impliedArity = constraint.target.fixedLength;
const endIndex = sourceArity - getEndElementCount(target.target, ElementFlags.Fixed);
const startIndex = endIndex - impliedArity;
Expand Down Expand Up @@ -31579,7 +31579,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// When the length is known and the index is after all spread elements we compute the offset from the element
// to the end and the number of ending fixed elements in the contextual tuple type.
const offset = length !== undefined && (lastSpreadIndex === undefined || index > lastSpreadIndex) ? length - index : 0;
const fixedEndLength = offset > 0 && t.target.hasRestElement ? getEndElementCount(t.target, ElementFlags.Fixed) : 0;
const fixedEndLength = offset > 0 && (t.target.combinedFlags & ElementFlags.Variable) ? getEndElementCount(t.target, ElementFlags.Fixed) : 0;
// If the offset is within the ending fixed part of the contextual tuple type, return the type of the contextual
// tuple element.
if (offset > 0 && offset <= fixedEndLength) {
Expand Down Expand Up @@ -37363,7 +37363,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// otherwise would return the type 'undefined').
const restType = getTypeOfSymbol(signature.parameters[paramCount]);
const index = pos - paramCount;
if (!isTupleType(restType) || restType.target.hasRestElement || index < restType.target.fixedLength) {
if (!isTupleType(restType) || restType.target.combinedFlags & ElementFlags.Variable || index < restType.target.fixedLength) {
return getIndexedAccessType(restType, getNumberLiteralType(index));
}
}
Expand Down Expand Up @@ -37412,7 +37412,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (signatureHasRestParameter(signature)) {
const restType = getTypeOfSymbol(signature.parameters[length - 1]);
if (isTupleType(restType)) {
return length + restType.target.fixedLength - (restType.target.hasRestElement ? 0 : 1);
return length + restType.target.fixedLength - (restType.target.combinedFlags & ElementFlags.Variable ? 0 : 1);
}
}
return length;
Expand Down Expand Up @@ -37457,7 +37457,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function hasEffectiveRestParameter(signature: Signature) {
if (signatureHasRestParameter(signature)) {
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
return !isTupleType(restType) || restType.target.hasRestElement;
return !isTupleType(restType) || !!(restType.target.combinedFlags & ElementFlags.Variable);
}
return false;
}
Expand All @@ -37468,7 +37468,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (!isTupleType(restType)) {
return isTypeAny(restType) ? anyArrayType : restType;
}
if (restType.target.hasRestElement) {
if (restType.target.combinedFlags & ElementFlags.Variable) {
return sliceTupleType(restType, restType.target.fixedLength);
}
}
Expand Down Expand Up @@ -40143,7 +40143,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
checkExpressionWithContextualType(initializer, contextualType, /*inferenceContext*/ undefined, checkMode || CheckMode.Normal)
: checkExpressionCached(initializer, checkMode));
return isParameter(declaration) && declaration.name.kind === SyntaxKind.ArrayBindingPattern &&
isTupleType(type) && !type.target.hasRestElement && getTypeReferenceArity(type) < declaration.name.elements.length ?
isTupleType(type) && !(type.target.combinedFlags & ElementFlags.Variable) && getTypeReferenceArity(type) < declaration.name.elements.length ?
padTupleType(type, declaration.name) : type;
}

Expand Down
6 changes: 5 additions & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6510,7 +6510,11 @@ export interface TupleType extends GenericType {
minLength: number;
/** Number of initial required or optional elements */
fixedLength: number;
/** True if tuple has any rest or variadic elements */
/**
* True if tuple has any rest or variadic elements
*
* @deprecated Use `.combinedFlags & ElementFlags.Variable` instead
*/
hasRestElement: boolean;
combinedFlags: ElementFlags;
readonly: boolean;
Expand Down
6 changes: 5 additions & 1 deletion tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6665,7 +6665,11 @@ declare namespace ts {
minLength: number;
/** Number of initial required or optional elements */
fixedLength: number;
/** True if tuple has any rest or variadic elements */
/**
* True if tuple has any rest or variadic elements
*
* @deprecated Use `.combinedFlags & ElementFlags.Variable` instead
*/
hasRestElement: boolean;
combinedFlags: ElementFlags;
readonly: boolean;
Expand Down