diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ee1d06112df..7f197370048 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12065,12 +12065,15 @@ namespace ts { return result; } } - else { - const instantiated = getTypeWithThisArgument(constraint, source); - if (result = isRelatedTo(instantiated, target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) { + // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed + else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) { errorInfo = saveErrorInfo; return result; - } + } + // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example + else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) { + errorInfo = saveErrorInfo; + return result; } } else if (source.flags & TypeFlags.Index) {