diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6abe6ad04b0..4f3a6225d88 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7316,7 +7316,16 @@ namespace ts { return result & TypeFlags.PropagatingFlags; } + // This function replaces substitution types in the given array with their underlying type parameter. + // We do this when creating type references and type alias instantiations because subsitution types are + // no longer necessary once the type arguments have been validated against their corresponding type + // parameter constraints. + function eraseSubstitutionTypes(types: Type[]) { + return sameMap(types, t => t.flags & TypeFlags.Substitution ? (t).typeParameter : t); + } + function createTypeReference(target: GenericType, typeArguments: Type[]): TypeReference { + typeArguments = eraseSubstitutionTypes(typeArguments); const id = getTypeListId(typeArguments); let type = target.instantiations.get(id); if (!type) { @@ -7383,6 +7392,7 @@ namespace ts { } function getTypeAliasInstantiation(symbol: Symbol, typeArguments: Type[]): Type { + typeArguments = eraseSubstitutionTypes(typeArguments); const type = getDeclaredTypeOfSymbol(symbol); const links = getSymbolLinks(symbol); const typeParameters = links.typeParameters; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f426370002b..c544334b7dd 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3703,6 +3703,10 @@ namespace ts { } // Type parameter substitution (TypeFlags.Substitution) + // Substitution types are created for type parameter references that occur in the true branch + // of a conditional type. For example, in 'T extends string ? Foo : Bar', the reference to + // T in Foo is resolved as a substitution type that substitutes 'string & T' for T. Thus, if + // Foo has a 'string' constraint on its type parameter, T will satisfy it. export interface SubstitutionType extends InstantiableType { typeParameter: TypeParameter; // Target type parameter substitute: Type; // Type to substitute for type parameter