@@ -8428,10 +8428,6 @@ namespace ts {
84288428 return links.resolvedType;
84298429 }
84308430
8431- function isGenericExtendsType(type: Type) {
8432- return maybeTypeOfKind(type, TypeFlags.Instantiable | TypeFlags.GenericMappedType);
8433- }
8434-
84358431 function createExtendsType(checkType: Type, extendsType: Type) {
84368432 const type = <ExtendsType>createType(TypeFlags.Extends);
84378433 type.checkType = checkType;
@@ -8447,9 +8443,16 @@ namespace ts {
84478443 if (checkType.flags & TypeFlags.Any) {
84488444 return booleanType;
84498445 }
8450- if (!isGenericExtendsType(checkType) && !isGenericExtendsType(extendsType)) {
8451- return isTypeAssignableTo(checkType, extendsType) ? trueType : falseType;
8446+ // Return trueType if type is definitely assignable
8447+ if (isTypeAssignableTo(checkType, extendsType)) {
8448+ return trueType;
8449+ }
8450+ // Return falseType is type is definitely not assignable
8451+ if (!isTypeAssignableTo(instantiateType(checkType, anyMapper), instantiateType(extendsType, constraintMapper))) {
8452+ // Type is definitely not assignable
8453+ return falseType;
84528454 }
8455+ // Type is possibly assignable, defer the check
84538456 const id = checkType.id + "," + extendsType.id;
84548457 let type = extendsTypes.get(id);
84558458 if (!type) {
@@ -8844,6 +8847,14 @@ namespace ts {
88448847 return t => t === source ? target : baseMapper(t);
88458848 }
88468849
8850+ function anyMapper(type: Type) {
8851+ return type.flags & TypeFlags.TypeParameter ? anyType : type;
8852+ }
8853+
8854+ function constraintMapper(type: Type) {
8855+ return type.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>type) || anyType : type;
8856+ }
8857+
88478858 function cloneTypeParameter(typeParameter: TypeParameter): TypeParameter {
88488859 const result = <TypeParameter>createType(TypeFlags.TypeParameter);
88498860 result.symbol = typeParameter.symbol;
0 commit comments