Skip to content

Commit e96ec8c

Browse files
committed
Erase substitution types in type references and type alias instantiations
1 parent 9598acd commit e96ec8c

2 files changed

Lines changed: 14 additions & 0 deletions

File tree

src/compiler/checker.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7316,7 +7316,16 @@ namespace ts {
73167316
return result & TypeFlags.PropagatingFlags;
73177317
}
73187318

7319+
// This function replaces substitution types in the given array with their underlying type parameter.
7320+
// We do this when creating type references and type alias instantiations because subsitution types are
7321+
// no longer necessary once the type arguments have been validated against their corresponding type
7322+
// parameter constraints.
7323+
function eraseSubstitutionTypes(types: Type[]) {
7324+
return sameMap(types, t => t.flags & TypeFlags.Substitution ? (<SubstitutionType>t).typeParameter : t);
7325+
}
7326+
73197327
function createTypeReference(target: GenericType, typeArguments: Type[]): TypeReference {
7328+
typeArguments = eraseSubstitutionTypes(typeArguments);
73207329
const id = getTypeListId(typeArguments);
73217330
let type = target.instantiations.get(id);
73227331
if (!type) {
@@ -7383,6 +7392,7 @@ namespace ts {
73837392
}
73847393

73857394
function getTypeAliasInstantiation(symbol: Symbol, typeArguments: Type[]): Type {
7395+
typeArguments = eraseSubstitutionTypes(typeArguments);
73867396
const type = getDeclaredTypeOfSymbol(symbol);
73877397
const links = getSymbolLinks(symbol);
73887398
const typeParameters = links.typeParameters;

src/compiler/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3703,6 +3703,10 @@ namespace ts {
37033703
}
37043704

37053705
// Type parameter substitution (TypeFlags.Substitution)
3706+
// Substitution types are created for type parameter references that occur in the true branch
3707+
// of a conditional type. For example, in 'T extends string ? Foo<T> : Bar<T>', the reference to
3708+
// T in Foo<T> is resolved as a substitution type that substitutes 'string & T' for T. Thus, if
3709+
// Foo<T> has a 'string' constraint on its type parameter, T will satisfy it.
37063710
export interface SubstitutionType extends InstantiableType {
37073711
typeParameter: TypeParameter; // Target type parameter
37083712
substitute: Type; // Type to substitute for type parameter

0 commit comments

Comments
 (0)