Skip to content

Commit 6a8f4cb

Browse files
committed
Delay tuple type constraint resolution
Create a new tuple that stores the this-type.
1 parent d34bbe5 commit 6a8f4cb

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4001,8 +4001,7 @@ namespace ts {
40014001
concatenate((<TypeReference>type).typeArguments, [thisArgument || (<TypeReference>type).target.thisType]));
40024002
}
40034003
if (type.flags & TypeFlags.Tuple) {
4004-
resolveTupleTypeMembers(type as TupleType, thisArgument);
4005-
return type;
4004+
return createTupleType((type as TupleType).elementTypes, thisArgument);
40064005
}
40074006
return type;
40084007
}
@@ -4104,11 +4103,11 @@ namespace ts {
41044103
return members;
41054104
}
41064105

4107-
function resolveTupleTypeMembers(type: TupleType, thisArgument?: Type) {
4106+
function resolveTupleTypeMembers(type: TupleType) {
41084107
const arrayElementType = getUnionType(type.elementTypes);
41094108
// Make the tuple type itself the 'this' type by including an extra type argument
41104109
// (Unless it's provided in the case that the tuple is a type parameter constraint)
4111-
const arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, thisArgument || type]));
4110+
const arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type.thisType || type]));
41124111
const members = createTupleTypeMemberSymbols(type.elementTypes);
41134112
addInheritedMembers(members, arrayType.properties);
41144113
setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexInfo, arrayType.numberIndexInfo);
@@ -5235,15 +5234,20 @@ namespace ts {
52355234
return links.resolvedType;
52365235
}
52375236

5238-
function createTupleType(elementTypes: Type[]) {
5239-
const id = getTypeListId(elementTypes);
5240-
return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes));
5237+
function createTupleType(elementTypes: Type[], thisType?: Type) {
5238+
let id = getTypeListId(elementTypes);
5239+
if (thisType) {
5240+
id += ',' + thisType.id;
5241+
}
5242+
5243+
return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes, thisType));
52415244
}
52425245

5243-
function createNewTupleType(elementTypes: Type[]) {
5246+
function createNewTupleType(elementTypes: Type[], thisType?: Type) {
52445247
const propagatedFlags = getPropagatingFlagsOfTypes(elementTypes, /*excludeKinds*/ 0);
52455248
const type = <TupleType>createObjectType(TypeFlags.Tuple | propagatedFlags);
52465249
type.elementTypes = elementTypes;
5250+
type.thisType = thisType;
52475251
return type;
52485252
}
52495253

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2371,6 +2371,7 @@ namespace ts {
23712371

23722372
export interface TupleType extends ObjectType {
23732373
elementTypes: Type[]; // Element types
2374+
thisType?: Type; // This-type of tuple (only needed for tuples that are constraints of type parameters)
23742375
}
23752376

23762377
export interface UnionOrIntersectionType extends Type {

0 commit comments

Comments
 (0)