@@ -12537,6 +12537,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
12537
12537
return needApparentType ? getApparentType(type) : type;
12538
12538
}
12539
12539
12540
+ function getThisArgument(type: Type) {
12541
+ return getObjectFlags(type) & ObjectFlags.Reference && length(getTypeArguments(type as TypeReference)) > getTypeReferenceArity(type as TypeReference) ? last(getTypeArguments(type as TypeReference)) : type;
12542
+ }
12543
+
12540
12544
function resolveObjectTypeMembers(type: ObjectType, source: InterfaceTypeWithDeclaredMembers, typeParameters: readonly TypeParameter[], typeArguments: readonly Type[]) {
12541
12545
let mapper: TypeMapper | undefined;
12542
12546
let members: SymbolTable;
@@ -12666,7 +12670,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
12666
12670
return [sig.parameters];
12667
12671
12668
12672
function expandSignatureParametersWithTupleMembers(restType: TupleTypeReference, restIndex: number) {
12669
- const elementTypes = getTypeArguments (restType);
12673
+ const elementTypes = getElementTypes (restType);
12670
12674
const associatedNames = getUniqAssociatedNamesFromTupleType(restType);
12671
12675
const restParams = map(elementTypes, (t, i) => {
12672
12676
// Lookup the label from the individual tuple passed in before falling back to the signature `rest` parameter name
@@ -13564,7 +13568,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
13564
13568
type.flags & TypeFlags.IndexedAccess && isConstTypeVariable((type as IndexedAccessType).objectType) ||
13565
13569
type.flags & TypeFlags.Conditional && isConstTypeVariable(getConstraintOfConditionalType(type as ConditionalType)) ||
13566
13570
type.flags & TypeFlags.Substitution && isConstTypeVariable((type as SubstitutionType).baseType) ||
13567
- isGenericTupleType(type) && findIndex(getTypeArguments (type), (t, i) => !!(type.target.elementFlags[i] & ElementFlags.Variadic) && isConstTypeVariable(t)) >= 0));
13571
+ isGenericTupleType(type) && findIndex(getElementTypes (type), (t, i) => !!(type.target.elementFlags[i] & ElementFlags.Variadic) && isConstTypeVariable(t)) >= 0));
13568
13572
}
13569
13573
13570
13574
function getConstraintOfIndexedAccess(type: IndexedAccessType) {
@@ -13718,7 +13722,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
13718
13722
return type.resolvedBaseConstraint;
13719
13723
}
13720
13724
const stack: object[] = [];
13721
- return type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), type);
13725
+ return type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), getThisArgument( type) );
13722
13726
13723
13727
function getImmediateBaseConstraint(t: Type): Type {
13724
13728
if (!t.immediateBaseConstraint) {
@@ -13821,12 +13825,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
13821
13825
return getBaseConstraint(getSubstitutionIntersection(t as SubstitutionType));
13822
13826
}
13823
13827
if (isGenericTupleType(t)) {
13824
- // We substitute constrains for variadic elements only when the constrains are array or tuple types
13825
- // as we want to avoid further (possibly unbounded) recursion.
13826
- const newElements = map(getTypeArguments(t), (v, i) => {
13827
- const constraint = t.target.elementFlags[i] & ElementFlags.Variadic ? getBaseConstraint(v) : undefined;
13828
- return constraint && everyType(constraint, isArrayOrTupleType) ? constraint : v;
13829
- });
13828
+ const newElements = map(getElementTypes(t), (v, i) => t.target.elementFlags[i] & ElementFlags.Variadic && getBaseConstraint(v) || v);
13830
13829
return createTupleType(newElements, t.target.elementFlags, t.target.readonly, t.target.labeledElementDeclarations);
13831
13830
}
13832
13831
return t;
@@ -16136,7 +16135,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
16136
16135
addElement(type, ElementFlags.Variadic, target.labeledElementDeclarations?.[i]);
16137
16136
}
16138
16137
else if (isTupleType(type)) {
16139
- const elements = getTypeArguments (type);
16138
+ const elements = getElementTypes (type);
16140
16139
if (elements.length + expandedTypes.length >= 10_000) {
16141
16140
error(currentNode, isPartOfTypeNode(currentNode!)
16142
16141
? Diagnostics.Type_produces_a_tuple_type_that_is_too_large_to_represent
@@ -16218,6 +16217,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
16218
16217
return type.elementFlags.length - findLastIndex(type.elementFlags, f => !(f & flags)) - 1;
16219
16218
}
16220
16219
16220
+ function getElementTypes(type: TupleTypeReference): readonly Type[] {
16221
+ const typeArguments = getTypeArguments(type);
16222
+ const arity = getTypeReferenceArity(type);
16223
+ return typeArguments.length === arity ? typeArguments : typeArguments.slice(0, arity);
16224
+ }
16225
+
16221
16226
function getTypeFromOptionalTypeNode(node: OptionalTypeNode): Type {
16222
16227
return addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true);
16223
16228
}
@@ -17746,7 +17751,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
17746
17751
}
17747
17752
17748
17753
function isDeferredType(type: Type, checkTuples: boolean) {
17749
- return isGenericType(type) || checkTuples && isTupleType(type) && some(getTypeArguments (type), isGenericType);
17754
+ return isGenericType(type) || checkTuples && isTupleType(type) && some(getElementTypes (type), isGenericType);
17750
17755
}
17751
17756
17752
17757
function getConditionalType(root: ConditionalRoot, mapper: TypeMapper | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
@@ -18885,7 +18890,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
18885
18890
// M<[A, B?, ...T, ...C[]] into [...M<[A]>, ...M<[B?]>, ...M<T>, ...M<C[]>] and then rely on tuple type
18886
18891
// normalization to resolve the non-generic parts of the resulting tuple.
18887
18892
const elementFlags = tupleType.target.elementFlags;
18888
- const elementTypes = map(getTypeArguments (tupleType), (t, i) => {
18893
+ const elementTypes = map(getElementTypes (tupleType), (t, i) => {
18889
18894
const singleton = elementFlags[i] & ElementFlags.Variadic ? t :
18890
18895
elementFlags[i] & ElementFlags.Rest ? createArrayType(t) :
18891
18896
createTupleType([t], [elementFlags[i]]);
@@ -18904,7 +18909,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
18904
18909
18905
18910
function instantiateMappedTupleType(tupleType: TupleTypeReference, mappedType: MappedType, mapper: TypeMapper) {
18906
18911
const elementFlags = tupleType.target.elementFlags;
18907
- const elementTypes = map(getTypeArguments (tupleType), (_, i) =>
18912
+ const elementTypes = map(getElementTypes (tupleType), (_, i) =>
18908
18913
instantiateMappedTypeTemplate(mappedType, getStringLiteralType("" + i), !!(elementFlags[i] & ElementFlags.Optional), mapper));
18909
18914
const modifiers = getMappedTypeModifiers(mappedType);
18910
18915
const newTupleModifiers = modifiers & MappedTypeModifiers.IncludeOptional ? map(elementFlags, f => f & ElementFlags.Required ? ElementFlags.Optional : f) :
@@ -20209,7 +20214,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
20209
20214
}
20210
20215
20211
20216
function getNormalizedTupleType(type: TupleTypeReference, writing: boolean): Type {
20212
- const elements = getTypeArguments (type);
20217
+ const elements = getElementTypes (type);
20213
20218
const normalizedElements = sameMap(elements, t => t.flags & TypeFlags.Simplifiable ? getSimplifiedType(t, writing) : t);
20214
20219
return elements !== normalizedElements ? createNormalizedTupleType(type.target, normalizedElements) : type;
20215
20220
}
@@ -24043,7 +24048,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
24043
24048
function isPartiallyInferableType(type: Type): boolean {
24044
24049
return !(getObjectFlags(type) & ObjectFlags.NonInferrableType) ||
24045
24050
isObjectLiteralType(type) && some(getPropertiesOfType(type), prop => isPartiallyInferableType(getTypeOfSymbol(prop))) ||
24046
- isTupleType(type) && some(getTypeArguments (type), isPartiallyInferableType);
24051
+ isTupleType(type) && some(getElementTypes (type), isPartiallyInferableType);
24047
24052
}
24048
24053
24049
24054
function createReverseMappedType(source: Type, target: MappedType, constraint: IndexType) {
@@ -24058,7 +24063,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
24058
24063
return createArrayType(inferReverseMappedType(getTypeArguments(source)[0], target, constraint), isReadonlyArrayType(source));
24059
24064
}
24060
24065
if (isTupleType(source)) {
24061
- const elementTypes = map(getTypeArguments (source), t => inferReverseMappedType(t, target, constraint));
24066
+ const elementTypes = map(getElementTypes (source), t => inferReverseMappedType(t, target, constraint));
24062
24067
const elementFlags = getMappedTypeModifiers(target) & MappedTypeModifiers.IncludeOptional ?
24063
24068
sameMap(source.target.elementFlags, f => f & ElementFlags.Optional ? ElementFlags.Required : f) :
24064
24069
source.target.elementFlags;
@@ -32398,7 +32403,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
32398
32403
function getMutableArrayOrTupleType(type: Type) {
32399
32404
return type.flags & TypeFlags.Union ? mapType(type, getMutableArrayOrTupleType) :
32400
32405
type.flags & TypeFlags.Any || isMutableArrayOrTuple(getBaseConstraintOfType(type) || type) ? type :
32401
- isTupleType(type) ? createTupleType(getTypeArguments (type), type.target.elementFlags, /*readonly*/ false, type.target.labeledElementDeclarations) :
32406
+ isTupleType(type) ? createTupleType(getElementTypes (type), type.target.elementFlags, /*readonly*/ false, type.target.labeledElementDeclarations) :
32402
32407
createTupleType([type], [ElementFlags.Variadic]);
32403
32408
}
32404
32409
@@ -32732,7 +32737,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
32732
32737
// We can call checkExpressionCached because spread expressions never have a contextual type.
32733
32738
const spreadType = arg.kind === SyntaxKind.SpreadElement && (flowLoopCount ? checkExpression((arg as SpreadElement).expression) : checkExpressionCached((arg as SpreadElement).expression));
32734
32739
if (spreadType && isTupleType(spreadType)) {
32735
- forEach(getTypeArguments (spreadType), (t, i) => {
32740
+ forEach(getElementTypes (spreadType), (t, i) => {
32736
32741
const flags = spreadType.target.elementFlags[i];
32737
32742
const syntheticArg = createSyntheticExpression(arg, flags & ElementFlags.Rest ? createArrayType(t) : t,
32738
32743
!!(flags & ElementFlags.Variable), spreadType.target.labeledElementDeclarations?.[i]);
@@ -37342,7 +37347,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
37342
37347
37343
37348
function padTupleType(type: TupleTypeReference, pattern: ArrayBindingPattern) {
37344
37349
const patternElements = pattern.elements;
37345
- const elementTypes = getTypeArguments (type).slice();
37350
+ const elementTypes = getElementTypes (type).slice();
37346
37351
const elementFlags = type.target.elementFlags.slice();
37347
37352
for (let i = getTypeReferenceArity(type); i < patternElements.length; i++) {
37348
37353
const e = patternElements[i];
0 commit comments