diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index be3965258a516..d951e183b0fa8 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -1008,7 +1008,6 @@ import {
     SignatureFlags,
     SignatureKind,
     singleElementArray,
-    SingleSignatureType,
     skipOuterExpressions,
     skipParentheses,
     skipTrivia,
@@ -7192,7 +7191,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
 
                 const abstractSignatures = filter(resolved.constructSignatures, signature => !!(signature.flags & SignatureFlags.Abstract));
                 if (some(abstractSignatures)) {
-                    const types = map(abstractSignatures, s => getOrCreateTypeFromSignature(s));
+                    const types = map(abstractSignatures, getOrCreateTypeFromSignature);
                     // count the number of type elements excluding abstract constructors
                     const typeElementCount = resolved.callSignatures.length +
                         (resolved.constructSignatures.length - abstractSignatures.length) +
@@ -16310,15 +16309,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
         return undefined;
     }
 
-    function getSignatureInstantiation(signature: Signature, typeArguments: readonly Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: readonly TypeParameter[]): Signature {
+    function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: readonly TypeParameter[]): Signature {
         const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
         if (inferredTypeParameters) {
             const returnSignature = getSingleCallOrConstructSignature(getReturnTypeOfSignature(instantiatedSignature));
             if (returnSignature) {
                 const newReturnSignature = cloneSignature(returnSignature);
                 newReturnSignature.typeParameters = inferredTypeParameters;
+                const newReturnType = getOrCreateTypeFromSignature(newReturnSignature) as AnonymousType;
+                newReturnType.mapper = instantiatedSignature.mapper;
                 const newInstantiatedSignature = cloneSignature(instantiatedSignature);
-                newInstantiatedSignature.resolvedReturnType = getOrCreateTypeFromSignature(newReturnSignature);
+                newInstantiatedSignature.resolvedReturnType = newReturnType;
                 return newInstantiatedSignature;
             }
         }
@@ -16378,16 +16379,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
         );
     }
 
-    function getImplementationSignature(signature: Signature) {
-        return signature.typeParameters ?
-            signature.implementationSignatureCache ||= createImplementationSignature(signature) :
-            signature;
-    }
-
-    function createImplementationSignature(signature: Signature) {
-        return signature.typeParameters ? instantiateSignature(signature, createTypeMapper([], [])) : signature;
-    }
-
     function getBaseSignature(signature: Signature) {
         const typeParameters = signature.typeParameters;
         if (typeParameters) {
@@ -16409,7 +16400,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
         return signature;
     }
 
-    function getOrCreateTypeFromSignature(signature: Signature, outerTypeParameters?: TypeParameter[]): ObjectType {
+    function getOrCreateTypeFromSignature(signature: Signature): ObjectType {
         // There are two ways to declare a construct signature, one is by declaring a class constructor
         // using the constructor keyword, and the other is declaring a bare construct signature in an
         // object type literal or interface (using the new keyword). Each way of declaring a constructor
@@ -16420,16 +16411,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
             // If declaration is undefined, it is likely to be the signature of the default constructor.
             const isConstructor = kind === undefined || kind === SyntaxKind.Constructor || kind === SyntaxKind.ConstructSignature || kind === SyntaxKind.ConstructorType;
 
-            // The type must have a symbol with a `Function` flag and a declaration in order to be correctly flagged as possibly containing
-            // type variables by `couldContainTypeVariables`
-            const type = createObjectType(ObjectFlags.Anonymous | ObjectFlags.SingleSignatureType, createSymbol(SymbolFlags.Function, InternalSymbolName.Function)) as SingleSignatureType;
-            if (signature.declaration && !nodeIsSynthesized(signature.declaration)) { // skip synthetic declarations - keeping those around could be bad, since they lack a parent pointer
-                type.symbol.declarations = [signature.declaration];
-                type.symbol.valueDeclaration = signature.declaration;
-            }
-            outerTypeParameters ||= signature.declaration && getOuterTypeParameters(signature.declaration, /*includeThisTypes*/ true);
-            type.outerTypeParameters = outerTypeParameters;
-
+            const type = createObjectType(ObjectFlags.Anonymous | ObjectFlags.SingleSignatureType, signature.declaration?.symbol);
             type.members = emptySymbols;
             type.properties = emptyArray;
             type.callSignatures = !isConstructor ? [signature] : emptyArray;
@@ -20419,6 +20401,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
         return createTypeMapper(map(forwardInferences, i => i.typeParameter), map(forwardInferences, () => unknownType));
     }
 
+    /**
+     * Return a type mapper that combines the context's return mapper with a mapper that erases any additional type parameters
+     * to their inferences at the time of creation.
+     */
+    function createOuterReturnMapper(context: InferenceContext) {
+        return context.outerReturnMapper ??= mergeTypeMappers(context.returnMapper, cloneInferenceContext(context).mapper);
+    }
+
     function combineTypeMappers(mapper1: TypeMapper | undefined, mapper2: TypeMapper): TypeMapper {
         return mapper1 ? makeCompositeTypeMapper(TypeMapKind.Composite, mapper1, mapper2) : mapper2;
     }
@@ -20515,7 +20505,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
         const links = getNodeLinks(declaration);
         const target = type.objectFlags & ObjectFlags.Reference ? links.resolvedType! as DeferredTypeReference :
             type.objectFlags & ObjectFlags.Instantiated ? type.target! : type;
-        let typeParameters = type.objectFlags & ObjectFlags.SingleSignatureType ? (type as SingleSignatureType).outerTypeParameters : links.outerTypeParameters;
+        let typeParameters = links.outerTypeParameters;
         if (!typeParameters) {
             // The first time an anonymous type is instantiated we compute and store a list of the type
             // parameters that are in scope (and therefore potentially referenced). For type literals that
@@ -20541,19 +20531,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
             const typeArguments = map(typeParameters, t => getMappedType(t, combinedMapper));
             const newAliasSymbol = aliasSymbol || type.aliasSymbol;
             const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper);
-            const id = (type.objectFlags & ObjectFlags.SingleSignatureType ? "S" : "") + getTypeListId(typeArguments) + getAliasId(newAliasSymbol, newAliasTypeArguments);
+            const id = getTypeListId(typeArguments) + getAliasId(newAliasSymbol, newAliasTypeArguments);
             if (!target.instantiations) {
                 target.instantiations = new Map<string, Type>();
                 target.instantiations.set(getTypeListId(typeParameters) + getAliasId(target.aliasSymbol, target.aliasTypeArguments), target);
             }
             let result = target.instantiations.get(id);
             if (!result) {
-                if (type.objectFlags & ObjectFlags.SingleSignatureType) {
-                    result = instantiateAnonymousType(type, mapper);
-                    target.instantiations.set(id, result);
-                    return result;
+                let newMapper = createTypeMapper(typeParameters, typeArguments);
+                if (target.objectFlags & ObjectFlags.SingleSignatureType && mapper) {
+                    newMapper = combineTypeMappers(newMapper, mapper);
                 }
-                const newMapper = createTypeMapper(typeParameters, typeArguments);
                 result = target.objectFlags & ObjectFlags.Reference ? createDeferredTypeReference((type as DeferredTypeReference).target, (type as DeferredTypeReference).node, newMapper, newAliasSymbol, newAliasTypeArguments) :
                     target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(target as MappedType, newMapper, newAliasSymbol, newAliasTypeArguments) :
                     instantiateAnonymousType(target, newMapper, newAliasSymbol, newAliasTypeArguments);
@@ -20751,9 +20739,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
         if (type.objectFlags & ObjectFlags.InstantiationExpressionType) {
             (result as InstantiationExpressionType).node = (type as InstantiationExpressionType).node;
         }
-        if (type.objectFlags & ObjectFlags.SingleSignatureType) {
-            (result as SingleSignatureType).outerTypeParameters = (type as SingleSignatureType).outerTypeParameters;
-        }
         result.target = type;
         result.mapper = mapper;
         result.aliasSymbol = aliasSymbol || type.aliasSymbol;
@@ -26116,7 +26101,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
         const result = !!(type.flags & TypeFlags.Instantiable ||
             type.flags & TypeFlags.Object && !isNonGenericTopLevelType(type) && (
                     objectFlags & ObjectFlags.Reference && ((type as TypeReference).node || some(getTypeArguments(type as TypeReference), couldContainTypeVariables)) ||
-                    objectFlags & ObjectFlags.SingleSignatureType && !!length((type as SingleSignatureType).outerTypeParameters) ||
                     objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ||
                     objectFlags & (ObjectFlags.Mapped | ObjectFlags.ReverseMapped | ObjectFlags.ObjectRestType | ObjectFlags.InstantiationExpressionType)
                 ) ||
@@ -26498,13 +26482,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
         }
     }
 
-    /**
-     * @returns `true` if `type` has the shape `[T[0]]` where `T` is `typeParameter`
-     */
-    function isTupleOfSelf(typeParameter: TypeParameter, type: Type) {
-        return isTupleType(type) && getTupleElementType(type, 0) === getIndexedAccessType(typeParameter, getNumberLiteralType(0)) && !getTypeOfPropertyOfType(type, "1" as __String);
-    }
-
     function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority = InferencePriority.None, contravariant = false) {
         let bivariant = false;
         let propagationType: Type;
@@ -26633,11 +26610,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                             inference.priority = priority;
                         }
                         if (priority === inference.priority) {
-                            // Inferring A to [A[0]] is a zero information inference (it guarantees A becomes its constraint), but oft arises from generic argument list inferences
-                            // By discarding it early, we can allow more fruitful results to be used instead.
-                            if (isTupleOfSelf(inference.typeParameter, candidate)) {
-                                return;
-                            }
                             // We make contravariant inferences only if we are in a pure contravariant position,
                             // i.e. only if we have not descended into a bivariant position.
                             if (contravariant && !bivariant) {
@@ -35577,8 +35549,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                     // from the return type. We need a separate inference pass here because (a) instantiation of
                     // the source type uses the outer context's return mapper (which excludes inferences made from
                     // outer arguments), and (b) we don't want any further inferences going into this context.
+                    // We use `createOuterReturnMapper` to ensure that all occurrences of outer type parameters are
+                    // replaced with inferences produced from the outer return type or preceding outer arguments.
+                    // This protects against circular inferences, i.e. avoiding situations where inferences reference
+                    // type parameters for which the inferences are being made.
                     const returnContext = createInferenceContext(signature.typeParameters!, signature, context.flags);
-                    const returnSourceType = instantiateType(contextualType, outerContext && outerContext.returnMapper);
+                    const returnSourceType = instantiateType(contextualType, outerContext && createOuterReturnMapper(outerContext));
                     inferTypes(returnContext.inferences, returnSourceType, inferenceTargetType);
                     context.returnMapper = some(returnContext.inferences, hasInferenceCandidates) ? getMapperFromContext(cloneInferredPartOfContext(returnContext)) : undefined;
                 }
@@ -35853,7 +35829,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
         checkMode: CheckMode,
         reportErrors: boolean,
         containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
-        inferenceContext: InferenceContext | undefined,
     ): readonly Diagnostic[] | undefined {
         const errorOutputContainer: ErrorOutputContainer = { errors: undefined, skipLogging: true };
         if (isJsxCallLike(node)) {
@@ -35888,10 +35863,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                 // If one or more arguments are still excluded (as indicated by CheckMode.SkipContextSensitive),
                 // we obtain the regular type of any object literal arguments because we may not have inferred complete
                 // parameter types yet and therefore excess property checks may yield false positives (see #17041).
-                const regularArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType;
-                // If this was inferred under a given inference context, we may need to instantiate the expression type to finish resolving
-                // the type variables in the expression.
-                const checkArgType = inferenceContext ? instantiateType(regularArgType, inferenceContext.nonFixingMapper) : regularArgType;
+                const checkArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType;
                 const effectiveCheckArgumentNode = getEffectiveCheckNode(arg);
                 if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? effectiveCheckArgumentNode : undefined, effectiveCheckArgumentNode, headMessage, containingMessageChain, errorOutputContainer)) {
                     Debug.assert(!reportErrors || !!errorOutputContainer.errors, "parameter should have errors when reporting errors");
@@ -36384,7 +36356,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                     if (headMessage) {
                         chain = chainDiagnosticMessages(chain, headMessage);
                     }
-                    const diags = getSignatureApplicabilityError(node, args, last, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain, /*inferenceContext*/ undefined);
+                    const diags = getSignatureApplicabilityError(node, args, last, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain);
                     if (diags) {
                         for (const d of diags) {
                             if (last.declaration && candidatesForArgumentError.length > 3) {
@@ -36406,7 +36378,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                     let i = 0;
                     for (const c of candidatesForArgumentError) {
                         const chain = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Overload_0_of_1_2_gave_the_following_error, i + 1, candidates.length, signatureToString(c));
-                        const diags = getSignatureApplicabilityError(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, chain, /*inferenceContext*/ undefined);
+                        const diags = getSignatureApplicabilityError(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, chain);
                         if (diags) {
                             if (diags.length <= min) {
                                 min = diags.length;
@@ -36495,7 +36467,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                 if (some(typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
                     return undefined;
                 }
-                if (getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined, /*inferenceContext*/ undefined)) {
+                if (getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
                     candidatesForArgumentError = [candidate];
                     return undefined;
                 }
@@ -36503,7 +36475,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
             }
 
             for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
-                let candidate = candidates[candidateIndex];
+                const candidate = candidates[candidateIndex];
                 if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
                     continue;
                 }
@@ -36512,14 +36484,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                 let inferenceContext: InferenceContext | undefined;
 
                 if (candidate.typeParameters) {
-                    // If we are *inside the body of candidate*, we need to create a clone of `candidate` with differing type parameter identities,
-                    // so our inference results for this call doesn't pollute expression types referencing the outer type parameter!
-                    const paramLocation = candidate.typeParameters[0].symbol.declarations?.[0]?.parent;
-                    const candidateParameterContext = paramLocation || (candidate.declaration && isConstructorDeclaration(candidate.declaration) ? candidate.declaration.parent : candidate.declaration);
-                    if (candidateParameterContext && findAncestor(node, a => a === candidateParameterContext)) {
-                        candidate = getImplementationSignature(candidate);
-                    }
-                    let typeArgumentTypes: readonly Type[] | undefined;
+                    let typeArgumentTypes: Type[] | undefined;
                     if (some(typeArguments)) {
                         typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
                         if (!typeArgumentTypes) {
@@ -36528,10 +36493,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                         }
                     }
                     else {
-                        inferenceContext = createInferenceContext(candidate.typeParameters!, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
-                        // The resulting type arguments are instantiated with the inference context mapper, as the inferred types may still contain references to the inference context's
-                        //  type variables via contextual projection. These are kept generic until all inferences are locked in, so the dependencies expressed can pass constraint checks.
-                        typeArgumentTypes = instantiateTypes(inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext), inferenceContext.nonFixingMapper);
+                        inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
+                        typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext);
                         argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal;
                     }
                     checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
@@ -36545,7 +36508,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                 else {
                     checkCandidate = candidate;
                 }
-                if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined, inferenceContext)) {
+                if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
                     // Give preference to error candidates that have no rest parameters (as they are more specific)
                     (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
                     continue;
@@ -36556,7 +36519,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                     // round of type inference and applicability checking for this particular candidate.
                     argCheckMode = CheckMode.Normal;
                     if (inferenceContext) {
-                        const typeArgumentTypes = instantiateTypes(inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext), inferenceContext.mapper);
+                        const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
                         checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters);
                         // If the original signature has a generic rest type, instantiation may produce a
                         // signature with different arity and we need to perform another arity check.
@@ -36565,7 +36528,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                             continue;
                         }
                     }
-                    if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined, inferenceContext)) {
+                    if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
                         // Give preference to error candidates that have no rest parameters (as they are more specific)
                         (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
                         continue;
@@ -41272,10 +41235,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                                 }
                             }
                         }
-                        // TODO: The signature may reference any outer inference contexts, but we map pop off and then apply new inference contexts, and thus get different inferred types.
-                        // That this is cached on the *first* such attempt is not currently an issue, since expression types *also* get cached on the first pass. If we ever properly speculate, though,
-                        // the cached "isolatedSignatureType" signature field absolutely needs to be included in the list of speculative caches.
-                        return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, context), flatMap(inferenceContexts, c => c && map(c.inferences, i => i.typeParameter)).slice());
+                        return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, context));
                     }
                 }
             }
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 5097d295f57ab..26ce72bd93582 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -6492,7 +6492,7 @@ export const enum ObjectFlags {
     CouldContainTypeVariablesComputed = 1 << 19, // CouldContainTypeVariables flag has been computed
     /** @internal */
     CouldContainTypeVariables = 1 << 20, // Type could contain a type variable
-
+    SingleSignatureType = 1 << 27, // A single signature type extracted from a potentially broader type
     ClassOrInterface = Class | Interface,
     /** @internal */
     RequiresWidening = ContainsWideningType | ContainsObjectOrArrayLiteral,
@@ -6508,7 +6508,6 @@ export const enum ObjectFlags {
     ContainsSpread   = 1 << 21,  // Object literal contains spread operation
     ObjectRestType   = 1 << 22,  // Originates in object rest declaration
     InstantiationExpressionType = 1 << 23,  // Originates in instantiation expression
-    SingleSignatureType = 1 << 27,  // A single signature type extracted from a potentially broader type
     /** @internal */
     IsClassInstanceClone = 1 << 24, // Type is a clone of a class instance type
     // Flags that require TypeFlags.Object and ObjectFlags.Reference
@@ -6723,12 +6722,6 @@ export interface AnonymousType extends ObjectType {
     instantiations?: Map<string, Type>; // Instantiations of generic type alias (undefined if non-generic)
 }
 
-/** @internal */
-// A SingleSignatureType may have bespoke outer type parameters to handle free type variable inferences
-export interface SingleSignatureType extends AnonymousType {
-    outerTypeParameters?: TypeParameter[];
-}
-
 /** @internal */
 export interface InstantiationExpressionType extends AnonymousType {
     node: NodeWithTypeArguments;
@@ -7014,8 +7007,6 @@ export interface Signature {
     isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
     /** @internal */
     instantiations?: Map<string, Signature>;    // Generic signature instantiation cache
-    /** @internal */
-    implementationSignatureCache?: Signature;  // Copy of the signature with fresh type parameters to use in checking the body of a potentially self-referential generic function (deferred)
 }
 
 export const enum IndexKind {
@@ -7123,6 +7114,7 @@ export interface InferenceContext {
     mapper: TypeMapper;                           // Mapper that fixes inferences
     nonFixingMapper: TypeMapper;                  // Mapper that doesn't fix inferences
     returnMapper?: TypeMapper;                    // Type mapper for inferences from return types (if any)
+    outerReturnMapper?: TypeMapper;               // Type mapper for inferences from return types of outer function (if any)
     inferredTypeParameters?: readonly TypeParameter[]; // Inferred type parameters for function result
     intraExpressionInferenceSites?: IntraExpressionInferenceSite[];
 }
diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts
index 2967f4534e175..b8c2606bf5ed4 100644
--- a/tests/baselines/reference/api/typescript.d.ts
+++ b/tests/baselines/reference/api/typescript.d.ts
@@ -6705,11 +6705,11 @@ declare namespace ts {
         JSLiteral = 4096,
         FreshLiteral = 8192,
         ArrayLiteral = 16384,
+        SingleSignatureType = 134217728,
         ClassOrInterface = 3,
         ContainsSpread = 2097152,
         ObjectRestType = 4194304,
         InstantiationExpressionType = 8388608,
-        SingleSignatureType = 134217728,
     }
     interface ObjectType extends Type {
         objectFlags: ObjectFlags;
diff --git a/tests/baselines/reference/declarationEmitHigherOrderRetainedGenerics.types b/tests/baselines/reference/declarationEmitHigherOrderRetainedGenerics.types
index 32975c6fe794a..1cb7b68c29b8f 100644
--- a/tests/baselines/reference/declarationEmitHigherOrderRetainedGenerics.types
+++ b/tests/baselines/reference/declarationEmitHigherOrderRetainedGenerics.types
@@ -2,7 +2,7 @@
 
 === Performance Stats ===
 Type Count: 1,000
-Instantiation count: 2,500 -> 5,000
+Instantiation count: 2,500
 
 === declarationEmitHigherOrderRetainedGenerics.ts ===
 export interface TypeLambda {
diff --git a/tests/baselines/reference/genericCallInferenceInConditionalTypes1.symbols b/tests/baselines/reference/genericCallInferenceInConditionalTypes1.symbols
new file mode 100644
index 0000000000000..7332aa25baa12
--- /dev/null
+++ b/tests/baselines/reference/genericCallInferenceInConditionalTypes1.symbols
@@ -0,0 +1,173 @@
+//// [tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts] ////
+
+=== genericCallInferenceInConditionalTypes1.ts ===
+// https://github.com/microsoft/TypeScript/issues/59937
+
+type Ref<T> = {
+>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 2, 9))
+
+  current: T;
+>current : Symbol(current, Decl(genericCallInferenceInConditionalTypes1.ts, 2, 15))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 2, 9))
+
+};
+
+type FunctionComponent<P> = (props: P) => unknown;
+>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 23))
+>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 29))
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 23))
+
+type ComponentProps<T extends FunctionComponent<any>> =
+>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 8, 20))
+>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))
+
+  T extends FunctionComponent<infer P> ? P : {};
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 8, 20))
+>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 35))
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 35))
+
+type PropsWithoutRef<P> = P extends any
+>PropsWithoutRef : Symbol(PropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 48))
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))
+
+  ? "ref" extends keyof P
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))
+
+    ? Omit<P, "ref">
+>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))
+
+    : P
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))
+
+  : P;
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))
+
+type ComponentPropsWithoutRef<T extends FunctionComponent<any>> =
+>ComponentPropsWithoutRef : Symbol(ComponentPropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 15, 6))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 17, 30))
+>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))
+
+  PropsWithoutRef<ComponentProps<T>>;
+>PropsWithoutRef : Symbol(PropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 48))
+>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 17, 30))
+
+declare function forwardRef<T, P>(
+>forwardRef : Symbol(forwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 18, 37))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 28))
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 30))
+
+  component: (props: P, ref: Ref<T>) => unknown,
+>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 34))
+>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 21, 14))
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 30))
+>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 21, 23))
+>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 28))
+
+): (props: P & { ref?: Ref<T> }) => unknown;
+>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 22, 4))
+>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 30))
+>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 22, 16))
+>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 28))
+
+const ComponentWithForwardRef = forwardRef(
+>ComponentWithForwardRef : Symbol(ComponentWithForwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 24, 5))
+>forwardRef : Symbol(forwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 18, 37))
+
+  <T extends FunctionComponent<any>>(
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 25, 3))
+>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))
+
+    props: ComponentPropsWithoutRef<T>,
+>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 25, 37))
+>ComponentPropsWithoutRef : Symbol(ComponentPropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 15, 6))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 25, 3))
+
+    ref: Ref<HTMLElement>,
+>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 26, 39))
+>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0))
+>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
+
+  ) => {
+    return null;
+  },
+);
+
+type Test<T> = T extends { component?: infer Component }
+>Test : Symbol(Test, Decl(genericCallInferenceInConditionalTypes1.ts, 31, 2))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 10))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 10))
+>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 26))
+>Component : Symbol(Component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 44))
+
+  ? Component extends FunctionComponent<any>
+>Component : Symbol(Component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 44))
+>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))
+
+    ? ComponentProps<Component>
+>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
+>Component : Symbol(Component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 44))
+
+    : never
+  : never;
+
+// the first one here has a chance to pollute the cache
+type Result1 = ComponentProps<typeof ComponentWithForwardRef>;
+>Result1 : Symbol(Result1, Decl(genericCallInferenceInConditionalTypes1.ts, 37, 10))
+>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
+>ComponentWithForwardRef : Symbol(ComponentWithForwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 24, 5))
+
+// that could be incorrectly reused by this one
+type Result2 = Test<{ component: typeof ComponentWithForwardRef }>; // no `T` leak
+>Result2 : Symbol(Result2, Decl(genericCallInferenceInConditionalTypes1.ts, 40, 62))
+>Test : Symbol(Test, Decl(genericCallInferenceInConditionalTypes1.ts, 31, 2))
+>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 42, 21))
+>ComponentWithForwardRef : Symbol(ComponentWithForwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 24, 5))
+
+// same as ComponentWithForwardRef above but using a resolved signature instead of a direct inferred result of `forwardRef`
+declare const ComponentWithForwardRef2: <T extends FunctionComponent<any>>(
+>ComponentWithForwardRef2 : Symbol(ComponentWithForwardRef2, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 13))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 41))
+>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))
+
+  props: PropsWithoutRef<ComponentProps<T>> & {
+>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 75))
+>PropsWithoutRef : Symbol(PropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 48))
+>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 41))
+
+    className?: string;
+>className : Symbol(className, Decl(genericCallInferenceInConditionalTypes1.ts, 46, 47))
+
+    as?: T | undefined;
+>as : Symbol(as, Decl(genericCallInferenceInConditionalTypes1.ts, 47, 23))
+>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 41))
+
+  } & {
+    ref?: Ref<HTMLElement> | undefined;
+>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 49, 7))
+>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0))
+>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
+
+  },
+) => unknown;
+
+type Result3 = ComponentProps<typeof ComponentWithForwardRef2>;
+>Result3 : Symbol(Result3, Decl(genericCallInferenceInConditionalTypes1.ts, 52, 13))
+>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
+>ComponentWithForwardRef2 : Symbol(ComponentWithForwardRef2, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 13))
+
+type Result4 = Test<{ component: typeof ComponentWithForwardRef2 }>;
+>Result4 : Symbol(Result4, Decl(genericCallInferenceInConditionalTypes1.ts, 54, 63))
+>Test : Symbol(Test, Decl(genericCallInferenceInConditionalTypes1.ts, 31, 2))
+>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 55, 21))
+>ComponentWithForwardRef2 : Symbol(ComponentWithForwardRef2, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 13))
+
diff --git a/tests/baselines/reference/genericCallInferenceInConditionalTypes1.types b/tests/baselines/reference/genericCallInferenceInConditionalTypes1.types
new file mode 100644
index 0000000000000..0257dab6a9720
--- /dev/null
+++ b/tests/baselines/reference/genericCallInferenceInConditionalTypes1.types
@@ -0,0 +1,151 @@
+//// [tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts] ////
+
+=== genericCallInferenceInConditionalTypes1.ts ===
+// https://github.com/microsoft/TypeScript/issues/59937
+
+type Ref<T> = {
+>Ref : Ref<T>
+>    : ^^^^^^
+
+  current: T;
+>current : T
+>        : ^
+
+};
+
+type FunctionComponent<P> = (props: P) => unknown;
+>FunctionComponent : FunctionComponent<P>
+>                  : ^^^^^^^^^^^^^^^^^^^^
+>props : P
+>      : ^
+
+type ComponentProps<T extends FunctionComponent<any>> =
+>ComponentProps : ComponentProps<T>
+>               : ^^^^^^^^^^^^^^^^^
+
+  T extends FunctionComponent<infer P> ? P : {};
+
+type PropsWithoutRef<P> = P extends any
+>PropsWithoutRef : PropsWithoutRef<P>
+>                : ^^^^^^^^^^^^^^^^^^
+
+  ? "ref" extends keyof P
+    ? Omit<P, "ref">
+    : P
+  : P;
+
+type ComponentPropsWithoutRef<T extends FunctionComponent<any>> =
+>ComponentPropsWithoutRef : ComponentPropsWithoutRef<T>
+>                         : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+  PropsWithoutRef<ComponentProps<T>>;
+
+declare function forwardRef<T, P>(
+>forwardRef : <T, P>(component: (props: P, ref: Ref<T>) => unknown) => (props: P & { ref?: Ref<T>; }) => unknown
+>           : ^ ^^ ^^         ^^                                  ^^^^^                                         
+
+  component: (props: P, ref: Ref<T>) => unknown,
+>component : (props: P, ref: Ref<T>) => unknown
+>          : ^     ^^ ^^   ^^      ^^^^^       
+>props : P
+>      : ^
+>ref : Ref<T>
+>    : ^^^^^^
+
+): (props: P & { ref?: Ref<T> }) => unknown;
+>props : P & { ref?: Ref<T>; }
+>      : ^^^^^^^^^^^^      ^^^
+>ref : Ref<T> | undefined
+>    : ^^^^^^^^^^^^^^^^^^
+
+const ComponentWithForwardRef = forwardRef(
+>ComponentWithForwardRef : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
+>                        : ^ ^^^^^^^^^                      ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^       
+>forwardRef(  <T extends FunctionComponent<any>>(    props: ComponentPropsWithoutRef<T>,    ref: Ref<HTMLElement>,  ) => {    return null;  },) : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
+>                                                                                                                                               : ^ ^^^^^^^^^                      ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^       
+>forwardRef : <T, P>(component: (props: P, ref: Ref<T>) => unknown) => (props: P & { ref?: Ref<T>; }) => unknown
+>           : ^ ^^ ^^         ^^                                  ^^^^^                                         
+
+  <T extends FunctionComponent<any>>(
+><T extends FunctionComponent<any>>(    props: ComponentPropsWithoutRef<T>,    ref: Ref<HTMLElement>,  ) => {    return null;  } : <T extends FunctionComponent<any>>(props: ComponentPropsWithoutRef<T>, ref: Ref<HTMLElement>) => null
+>                                                                                                                                : ^ ^^^^^^^^^                      ^^     ^^                           ^^   ^^                ^^^^^^^^^
+
+    props: ComponentPropsWithoutRef<T>,
+>props : PropsWithoutRef<ComponentProps<T>>
+>      : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+    ref: Ref<HTMLElement>,
+>ref : Ref<HTMLElement>
+>    : ^^^^^^^^^^^^^^^^
+
+  ) => {
+    return null;
+  },
+);
+
+type Test<T> = T extends { component?: infer Component }
+>Test : Test<T>
+>     : ^^^^^^^
+>component : Component | undefined
+>          : ^^^^^^^^^^^^^^^^^^^^^
+
+  ? Component extends FunctionComponent<any>
+    ? ComponentProps<Component>
+    : never
+  : never;
+
+// the first one here has a chance to pollute the cache
+type Result1 = ComponentProps<typeof ComponentWithForwardRef>;
+>Result1 : Omit<any, "ref"> & { ref?: Ref<HTMLElement> | undefined; }
+>        : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>ComponentWithForwardRef : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
+>                        : ^ ^^^^^^^^^                      ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^       
+
+// that could be incorrectly reused by this one
+type Result2 = Test<{ component: typeof ComponentWithForwardRef }>; // no `T` leak
+>Result2 : Omit<any, "ref"> & { ref?: Ref<HTMLElement> | undefined; }
+>        : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>component : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
+>          : ^ ^^^^^^^^^                      ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^       
+>ComponentWithForwardRef : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
+>                        : ^ ^^^^^^^^^                      ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^       
+
+// same as ComponentWithForwardRef above but using a resolved signature instead of a direct inferred result of `forwardRef`
+declare const ComponentWithForwardRef2: <T extends FunctionComponent<any>>(
+>ComponentWithForwardRef2 : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { className?: string; as?: T | undefined; } & { ref?: Ref<HTMLElement> | undefined; }) => unknown
+>                         : ^ ^^^^^^^^^                      ^^     ^^                                                                                                                          ^^^^^       
+
+  props: PropsWithoutRef<ComponentProps<T>> & {
+>props : PropsWithoutRef<ComponentProps<T>> & { className?: string; as?: T | undefined; } & { ref?: Ref<HTMLElement> | undefined; }
+>      : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^      ^^^^^^^             ^^^^^^^^^^^^^^                            ^^^
+
+    className?: string;
+>className : string | undefined
+>          : ^^^^^^^^^^^^^^^^^^
+
+    as?: T | undefined;
+>as : T | undefined
+>   : ^^^^^^^^^^^^^
+
+  } & {
+    ref?: Ref<HTMLElement> | undefined;
+>ref : Ref<HTMLElement> | undefined
+>    : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+  },
+) => unknown;
+
+type Result3 = ComponentProps<typeof ComponentWithForwardRef2>;
+>Result3 : Omit<any, "ref"> & { className?: string; as?: FunctionComponent<any> | undefined; } & { ref?: Ref<HTMLElement> | undefined; }
+>        : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                            ^^^
+>ComponentWithForwardRef2 : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { className?: string; as?: T | undefined; } & { ref?: Ref<HTMLElement> | undefined; }) => unknown
+>                         : ^ ^^^^^^^^^                      ^^     ^^                                                                                                                          ^^^^^       
+
+type Result4 = Test<{ component: typeof ComponentWithForwardRef2 }>;
+>Result4 : Omit<any, "ref"> & { className?: string; as?: FunctionComponent<any> | undefined; } & { ref?: Ref<HTMLElement> | undefined; }
+>        : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                            ^^^
+>component : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { className?: string; as?: T | undefined; } & { ref?: Ref<HTMLElement> | undefined; }) => unknown
+>          : ^ ^^^^^^^^^                      ^^     ^^                                                                                                                          ^^^^^       
+>ComponentWithForwardRef2 : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { className?: string; as?: T | undefined; } & { ref?: Ref<HTMLElement> | undefined; }) => unknown
+>                         : ^ ^^^^^^^^^                      ^^     ^^                                                                                                                          ^^^^^       
+
diff --git a/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.symbols b/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.symbols
new file mode 100644
index 0000000000000..d7a63d38d355d
--- /dev/null
+++ b/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.symbols
@@ -0,0 +1,168 @@
+//// [tests/cases/compiler/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts] ////
+
+=== genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts ===
+declare const EffectTypeId: unique symbol;
+>EffectTypeId : Symbol(EffectTypeId, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 0, 13))
+
+interface Variance<out A, out E, out R> {
+>Variance : Symbol(Variance, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 0, 42))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 19))
+>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 25))
+>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 32))
+
+  readonly [EffectTypeId]: VarianceStruct<A, E, R>;
+>[EffectTypeId] : Symbol(Variance[EffectTypeId], Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 41))
+>EffectTypeId : Symbol(EffectTypeId, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 0, 13))
+>VarianceStruct : Symbol(VarianceStruct, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 6, 36))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 19))
+>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 25))
+>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 32))
+}
+
+type Covariant<A> = (_: never) => A;
+>Covariant : Symbol(Covariant, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 4, 1))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 6, 15))
+>_ : Symbol(_, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 6, 21))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 6, 15))
+
+interface VarianceStruct<out A, out E, out R> {
+>VarianceStruct : Symbol(VarianceStruct, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 6, 36))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 25))
+>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 31))
+>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 38))
+
+  readonly _V: string;
+>_V : Symbol(VarianceStruct._V, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 47))
+
+  readonly _A: Covariant<A>;
+>_A : Symbol(VarianceStruct._A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 9, 22))
+>Covariant : Symbol(Covariant, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 4, 1))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 25))
+
+  readonly _E: Covariant<E>;
+>_E : Symbol(VarianceStruct._E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 10, 28))
+>Covariant : Symbol(Covariant, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 4, 1))
+>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 31))
+
+  readonly _R: Covariant<R>;
+>_R : Symbol(VarianceStruct._R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 11, 28))
+>Covariant : Symbol(Covariant, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 4, 1))
+>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 38))
+}
+
+interface Effect<out A, out E = never, out R = never>
+>Effect : Symbol(Effect, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 13, 1))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 17))
+>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 23))
+>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 38))
+
+  extends Variance<A, E, R> {}
+>Variance : Symbol(Variance, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 0, 42))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 17))
+>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 23))
+>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 38))
+
+declare const succeed: <A>(value: A) => Effect<A>;
+>succeed : Symbol(succeed, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 13))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 24))
+>value : Symbol(value, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 27))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 24))
+>Effect : Symbol(Effect, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 13, 1))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 24))
+
+type F<X, Y> = Y extends { _type: infer Z }
+>F : Symbol(F, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 50))
+>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 7))
+>Y : Symbol(Y, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 9))
+>Y : Symbol(Y, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 9))
+>_type : Symbol(_type, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 26))
+>Z : Symbol(Z, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 39))
+
+  ? X extends Effect<infer A, infer E, infer R>
+>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 7))
+>Effect : Symbol(Effect, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 13, 1))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 26))
+>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 35))
+>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 44))
+
+    ? Effect<A, E, R | Z>
+>Effect : Symbol(Effect, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 13, 1))
+>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 26))
+>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 35))
+>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 44))
+>Z : Symbol(Z, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 39))
+
+    : X
+>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 7))
+
+  : X;
+>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 7))
+
+type ProxyMap<Service> = {
+>ProxyMap : Symbol(ProxyMap, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 24, 6))
+>Service : Symbol(Service, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 26, 14))
+
+  [K in keyof Service]: (Service & { _type: Service })[K];
+>K : Symbol(K, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 27, 3))
+>Service : Symbol(Service, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 26, 14))
+>Service : Symbol(Service, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 26, 14))
+>_type : Symbol(_type, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 27, 36))
+>Service : Symbol(Service, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 26, 14))
+>K : Symbol(K, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 27, 3))
+
+};
+
+declare const implement: <T>() => <I extends ReadonlyArray<any>, X>(
+>implement : Symbol(implement, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 13))
+>T : Symbol(T, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 26))
+>I : Symbol(I, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 35))
+>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
+>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 64))
+
+  x: (...i: I) => X,
+>x : Symbol(x, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 68))
+>i : Symbol(i, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 31, 6))
+>I : Symbol(I, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 35))
+>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 64))
+
+) => (...i: I) => F<X, T>;
+>i : Symbol(i, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 32, 6))
+>I : Symbol(I, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 35))
+>F : Symbol(F, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 50))
+>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 64))
+>T : Symbol(T, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 26))
+
+class XXX {
+>XXX : Symbol(XXX, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 32, 26))
+
+  log = implement<this>()(<N extends number>(n: N) => succeed(n));
+>log : Symbol(XXX.log, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 34, 11))
+>implement : Symbol(implement, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 13))
+>N : Symbol(N, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 35, 27))
+>n : Symbol(n, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 35, 45))
+>N : Symbol(N, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 35, 27))
+>succeed : Symbol(succeed, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 13))
+>n : Symbol(n, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 35, 45))
+}
+
+export declare const inner: XXX;
+>inner : Symbol(inner, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 38, 20))
+>XXX : Symbol(XXX, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 32, 26))
+
+export declare const outer: ProxyMap<XXX>;
+>outer : Symbol(outer, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 39, 20))
+>ProxyMap : Symbol(ProxyMap, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 24, 6))
+>XXX : Symbol(XXX, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 32, 26))
+
+export const a = inner.log(100); // Effect<100, never, never>
+>a : Symbol(a, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 41, 12))
+>inner.log : Symbol(XXX.log, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 34, 11))
+>inner : Symbol(inner, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 38, 20))
+>log : Symbol(XXX.log, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 34, 11))
+
+export const b = outer.log(100); // Effect<100, never, XXX>
+>b : Symbol(b, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 42, 12))
+>outer.log : Symbol(log, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 34, 11))
+>outer : Symbol(outer, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 39, 20))
+>log : Symbol(log, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 34, 11))
+
diff --git a/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.types b/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.types
new file mode 100644
index 0000000000000..6ff710a93595e
--- /dev/null
+++ b/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.types
@@ -0,0 +1,144 @@
+//// [tests/cases/compiler/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts] ////
+
+=== genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts ===
+declare const EffectTypeId: unique symbol;
+>EffectTypeId : unique symbol
+>             : ^^^^^^^^^^^^^
+
+interface Variance<out A, out E, out R> {
+  readonly [EffectTypeId]: VarianceStruct<A, E, R>;
+>[EffectTypeId] : VarianceStruct<A, E, R>
+>               : ^^^^^^^^^^^^^^^^^^^^^^^
+>EffectTypeId : unique symbol
+>             : ^^^^^^^^^^^^^
+}
+
+type Covariant<A> = (_: never) => A;
+>Covariant : Covariant<A>
+>          : ^^^^^^^^^^^^
+>_ : never
+>  : ^^^^^
+
+interface VarianceStruct<out A, out E, out R> {
+  readonly _V: string;
+>_V : string
+>   : ^^^^^^
+
+  readonly _A: Covariant<A>;
+>_A : Covariant<A>
+>   : ^^^^^^^^^^^^
+
+  readonly _E: Covariant<E>;
+>_E : Covariant<E>
+>   : ^^^^^^^^^^^^
+
+  readonly _R: Covariant<R>;
+>_R : Covariant<R>
+>   : ^^^^^^^^^^^^
+}
+
+interface Effect<out A, out E = never, out R = never>
+  extends Variance<A, E, R> {}
+
+declare const succeed: <A>(value: A) => Effect<A>;
+>succeed : <A>(value: A) => Effect<A>
+>        : ^ ^^     ^^ ^^^^^         
+>value : A
+>      : ^
+
+type F<X, Y> = Y extends { _type: infer Z }
+>F : F<X, Y>
+>  : ^^^^^^^
+>_type : Z
+>      : ^
+
+  ? X extends Effect<infer A, infer E, infer R>
+    ? Effect<A, E, R | Z>
+    : X
+  : X;
+
+type ProxyMap<Service> = {
+>ProxyMap : ProxyMap<Service>
+>         : ^^^^^^^^^^^^^^^^^
+
+  [K in keyof Service]: (Service & { _type: Service })[K];
+>_type : Service
+>      : ^^^^^^^
+
+};
+
+declare const implement: <T>() => <I extends ReadonlyArray<any>, X>(
+>implement : <T>() => <I extends ReadonlyArray<any>, X>(x: (...i: I) => X) => (...i: I) => F<X, T>
+>          : ^ ^^^^^^^                                                                            
+
+  x: (...i: I) => X,
+>x : (...i: I) => X
+>  : ^^^^ ^^ ^^^^^ 
+>i : I
+>  : ^
+
+) => (...i: I) => F<X, T>;
+>i : I
+>  : ^
+
+class XXX {
+>XXX : XXX
+>    : ^^^
+
+  log = implement<this>()(<N extends number>(n: N) => succeed(n));
+>log : <N extends number>(n: N) => F<Effect<N, never, never>, this>
+>    : ^ ^^^^^^^^^      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>implement<this>()(<N extends number>(n: N) => succeed(n)) : <N extends number>(n: N) => F<Effect<N, never, never>, this>
+>                                                          : ^ ^^^^^^^^^      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>implement<this>() : <I extends ReadonlyArray<any>, X>(x: (...i: I) => X) => (...i: I) => F<X, this>
+>                  : ^ ^^^^^^^^^                  ^^ ^^ ^^^^^^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^
+>implement : <T>() => <I extends ReadonlyArray<any>, X>(x: (...i: I) => X) => (...i: I) => F<X, T>
+>          : ^ ^^^^^^^                                                                            
+><N extends number>(n: N) => succeed(n) : <N extends number>(n: N) => Effect<N, never, never>
+>                                       : ^ ^^^^^^^^^      ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>n : N
+>  : ^
+>succeed(n) : Effect<N, never, never>
+>           : ^^^^^^^^^^^^^^^^^^^^^^^
+>succeed : <A>(value: A) => Effect<A>
+>        : ^ ^^     ^^ ^^^^^         
+>n : N
+>  : ^
+}
+
+export declare const inner: XXX;
+>inner : XXX
+>      : ^^^
+
+export declare const outer: ProxyMap<XXX>;
+>outer : ProxyMap<XXX>
+>      : ^^^^^^^^^^^^^
+
+export const a = inner.log(100); // Effect<100, never, never>
+>a : F<Effect<100, never, never>, this>
+>  : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>inner.log(100) : F<Effect<100, never, never>, this>
+>               : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>inner.log : <N extends number>(n: N) => F<Effect<N, never, never>, this>
+>          : ^ ^^^^^^^^^      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>inner : XXX
+>      : ^^^
+>log : <N extends number>(n: N) => F<Effect<N, never, never>, this>
+>    : ^ ^^^^^^^^^      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>100 : 100
+>    : ^^^
+
+export const b = outer.log(100); // Effect<100, never, XXX>
+>b : F<Effect<100, never, never>, this>
+>  : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>outer.log(100) : F<Effect<100, never, never>, this>
+>               : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>outer.log : <N extends number>(n: N) => F<Effect<N, never, never>, this>
+>          : ^ ^^^^^^^^^      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>outer : ProxyMap<XXX>
+>      : ^^^^^^^^^^^^^
+>log : <N extends number>(n: N) => F<Effect<N, never, never>, this>
+>    : ^ ^^^^^^^^^      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>100 : 100
+>    : ^^^
+
diff --git a/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.symbols b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.symbols
index dec6af6bac2c5..9dd6d91bb1f7d 100644
--- a/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.symbols
+++ b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.symbols
@@ -42,3 +42,60 @@ const added2 = addP2({ bar: 2 });
 >addP2 : Symbol(addP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 9, 5))
 >bar : Symbol(bar, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 22))
 
+function withP3<P>(p: P) {
+>withP3 : Symbol(withP3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 33))
+>P : Symbol(P, Decl(genericCallInferenceWithGenericLocalFunction.ts, 12, 16))
+>p : Symbol(p, Decl(genericCallInferenceWithGenericLocalFunction.ts, 12, 19))
+>P : Symbol(P, Decl(genericCallInferenceWithGenericLocalFunction.ts, 12, 16))
+
+  const m =
+>m : Symbol(m, Decl(genericCallInferenceWithGenericLocalFunction.ts, 13, 7))
+
+    <I,>(from: I) =>
+>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 14, 5))
+>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 14, 9))
+>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 14, 5))
+
+    <I2,>(from2: I2) => ({ ...from, ...from2, ...p });
+>I2 : Symbol(I2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 15, 5))
+>from2 : Symbol(from2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 15, 10))
+>I2 : Symbol(I2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 15, 5))
+>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 14, 9))
+>from2 : Symbol(from2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 15, 10))
+>p : Symbol(p, Decl(genericCallInferenceWithGenericLocalFunction.ts, 12, 19))
+
+  return createTransform(m);
+>createTransform : Symbol(createTransform, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 5))
+>m : Symbol(m, Decl(genericCallInferenceWithGenericLocalFunction.ts, 13, 7))
+}
+
+const addP3 = withP3({ a: 1 });
+>addP3 : Symbol(addP3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 19, 5))
+>withP3 : Symbol(withP3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 33))
+>a : Symbol(a, Decl(genericCallInferenceWithGenericLocalFunction.ts, 19, 22))
+
+const addedSome3 = addP3({ b: '' });
+>addedSome3 : Symbol(addedSome3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 20, 5))
+>addP3 : Symbol(addP3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 19, 5))
+>b : Symbol(b, Decl(genericCallInferenceWithGenericLocalFunction.ts, 20, 26))
+
+const added3 = addedSome3({ c: true });
+>added3 : Symbol(added3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 21, 5))
+>addedSome3 : Symbol(addedSome3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 20, 5))
+>c : Symbol(c, Decl(genericCallInferenceWithGenericLocalFunction.ts, 21, 27))
+
+const addP3_other = withP3({ foo: 'bar' });
+>addP3_other : Symbol(addP3_other, Decl(genericCallInferenceWithGenericLocalFunction.ts, 23, 5))
+>withP3 : Symbol(withP3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 33))
+>foo : Symbol(foo, Decl(genericCallInferenceWithGenericLocalFunction.ts, 23, 28))
+
+const addedSome3_other = addP3_other({ qwerty: 123 });
+>addedSome3_other : Symbol(addedSome3_other, Decl(genericCallInferenceWithGenericLocalFunction.ts, 24, 5))
+>addP3_other : Symbol(addP3_other, Decl(genericCallInferenceWithGenericLocalFunction.ts, 23, 5))
+>qwerty : Symbol(qwerty, Decl(genericCallInferenceWithGenericLocalFunction.ts, 24, 38))
+
+const added3_other = addedSome3_other({ bazinga: true });
+>added3_other : Symbol(added3_other, Decl(genericCallInferenceWithGenericLocalFunction.ts, 25, 5))
+>addedSome3_other : Symbol(addedSome3_other, Decl(genericCallInferenceWithGenericLocalFunction.ts, 24, 5))
+>bazinga : Symbol(bazinga, Decl(genericCallInferenceWithGenericLocalFunction.ts, 25, 39))
+
diff --git a/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.types b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.types
index a49703b695d51..eba6fd0e72fb2 100644
--- a/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.types
+++ b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.types
@@ -74,3 +74,128 @@ const added2 = addP2({ bar: 2 });
 >2 : 2
 >  : ^
 
+function withP3<P>(p: P) {
+>withP3 : <P>(p: P) => <I>(from: I) => <I2>(from2: I2) => I & I2 & P
+>       : ^ ^^ ^^ ^^^^^^ ^^    ^^^^^^^^^  ^^     ^^  ^^^^^^^^^^^^^^^
+>p : P
+>  : ^
+
+  const m =
+>m : <I>(from: I) => <I2>(from2: I2) => I & I2 & P
+>  : ^ ^^    ^^ ^^^^^^  ^^         ^^^^^^^^^^^^^^^
+
+    <I,>(from: I) =>
+><I,>(from: I) =>    <I2,>(from2: I2) => ({ ...from, ...from2, ...p }) : <I>(from: I) => <I2>(from2: I2) => I & I2 & P
+>                                                                      : ^ ^^    ^^ ^^^^^^  ^^         ^^^^^^^^^^^^^^^
+>from : I
+>     : ^
+
+    <I2,>(from2: I2) => ({ ...from, ...from2, ...p });
+><I2,>(from2: I2) => ({ ...from, ...from2, ...p }) : <I2>(from2: I2) => I & I2 & P
+>                                                  : ^  ^^     ^^  ^^^^^^^^^^^^^^^
+>from2 : I2
+>      : ^^
+>({ ...from, ...from2, ...p }) : I & I2 & P
+>                              : ^^^^^^^^^^
+>{ ...from, ...from2, ...p } : I & I2 & P
+>                            : ^^^^^^^^^^
+>from : I
+>     : ^
+>from2 : I2
+>      : ^^
+>p : P
+>  : ^
+
+  return createTransform(m);
+>createTransform(m) : <I>(from: I) => <I2>(from2: I2) => I & I2 & P
+>                   : ^ ^^    ^^^^^^^^^  ^^     ^^  ^^^^^^^^^^^^^^^
+>createTransform : <I, O>(tr: (from: I) => O) => (from: I) => O
+>                : ^ ^^ ^^  ^^              ^^^^^^    ^^ ^^^^^ 
+>m : <I>(from: I) => <I2>(from2: I2) => I & I2 & P
+>  : ^ ^^    ^^ ^^^^^^  ^^         ^^^^^^^^^^^^^^^
+}
+
+const addP3 = withP3({ a: 1 });
+>addP3 : <I>(from: I) => <I2>(from2: I2) => I & I2 & { a: number; }
+>      : ^ ^^    ^^^^^^^^^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>withP3({ a: 1 }) : <I>(from: I) => <I2>(from2: I2) => I & I2 & { a: number; }
+>                 : ^ ^^    ^^^^^^^^^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>withP3 : <P>(p: P) => <I>(from: I) => <I2>(from2: I2) => I & I2 & P
+>       : ^ ^^ ^^ ^^^^^^ ^^    ^^^^^^^^^  ^^     ^^  ^^^^^^^^^^^^^^^
+>{ a: 1 } : { a: number; }
+>         : ^^^^^^^^^^^^^^
+>a : number
+>  : ^^^^^^
+>1 : 1
+>  : ^
+
+const addedSome3 = addP3({ b: '' });
+>addedSome3 : <I2>(from2: I2) => { b: string; } & I2 & { a: number; }
+>           : ^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>addP3({ b: '' }) : <I2>(from2: I2) => { b: string; } & I2 & { a: number; }
+>                 : ^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>addP3 : <I>(from: I) => <I2>(from2: I2) => I & I2 & { a: number; }
+>      : ^ ^^    ^^^^^^^^^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>{ b: '' } : { b: string; }
+>          : ^^^^^^^^^^^^^^
+>b : string
+>  : ^^^^^^
+>'' : ""
+>   : ^^
+
+const added3 = addedSome3({ c: true });
+>added3 : { b: string; } & { c: boolean; } & { a: number; }
+>       : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>addedSome3({ c: true }) : { b: string; } & { c: boolean; } & { a: number; }
+>                        : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>addedSome3 : <I2>(from2: I2) => { b: string; } & I2 & { a: number; }
+>           : ^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>{ c: true } : { c: true; }
+>            : ^^^^^^^^^^^^
+>c : true
+>  : ^^^^
+>true : true
+>     : ^^^^
+
+const addP3_other = withP3({ foo: 'bar' });
+>addP3_other : <I>(from: I) => <I2>(from2: I2) => I & I2 & { foo: string; }
+>            : ^ ^^    ^^^^^^^^^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>withP3({ foo: 'bar' }) : <I>(from: I) => <I2>(from2: I2) => I & I2 & { foo: string; }
+>                       : ^ ^^    ^^^^^^^^^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>withP3 : <P>(p: P) => <I>(from: I) => <I2>(from2: I2) => I & I2 & P
+>       : ^ ^^ ^^ ^^^^^^ ^^    ^^^^^^^^^  ^^     ^^  ^^^^^^^^^^^^^^^
+>{ foo: 'bar' } : { foo: string; }
+>               : ^^^^^^^^^^^^^^^^
+>foo : string
+>    : ^^^^^^
+>'bar' : "bar"
+>      : ^^^^^
+
+const addedSome3_other = addP3_other({ qwerty: 123 });
+>addedSome3_other : <I2>(from2: I2) => { qwerty: number; } & I2 & { foo: string; }
+>                 : ^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>addP3_other({ qwerty: 123 }) : <I2>(from2: I2) => { qwerty: number; } & I2 & { foo: string; }
+>                             : ^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>addP3_other : <I>(from: I) => <I2>(from2: I2) => I & I2 & { foo: string; }
+>            : ^ ^^    ^^^^^^^^^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>{ qwerty: 123 } : { qwerty: number; }
+>                : ^^^^^^^^^^^^^^^^^^^
+>qwerty : number
+>       : ^^^^^^
+>123 : 123
+>    : ^^^
+
+const added3_other = addedSome3_other({ bazinga: true });
+>added3_other : { qwerty: number; } & { bazinga: boolean; } & { foo: string; }
+>             : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>addedSome3_other({ bazinga: true }) : { qwerty: number; } & { bazinga: boolean; } & { foo: string; }
+>                                    : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>addedSome3_other : <I2>(from2: I2) => { qwerty: number; } & I2 & { foo: string; }
+>                 : ^  ^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+>{ bazinga: true } : { bazinga: true; }
+>                  : ^^^^^^^^^^^^^^^^^^
+>bazinga : true
+>        : ^^^^
+>true : true
+>     : ^^^^
+
diff --git a/tests/baselines/reference/genericFunctionInference1.types b/tests/baselines/reference/genericFunctionInference1.types
index 7275fd51f97be..93ff8f85b3541 100644
--- a/tests/baselines/reference/genericFunctionInference1.types
+++ b/tests/baselines/reference/genericFunctionInference1.types
@@ -2,7 +2,7 @@
 
 === Performance Stats ===
 Type Count: 1,000
-Instantiation count: 2,500
+Instantiation count: 1,000
 
 === genericFunctionInference1.ts ===
 declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
diff --git a/tests/baselines/reference/inferenceFromGenericClassNoCrash1.errors.txt b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.errors.txt
new file mode 100644
index 0000000000000..6103c38d6d74a
--- /dev/null
+++ b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.errors.txt
@@ -0,0 +1,14 @@
+inferenceFromGenericClassNoCrash1.ts(5,3): error TS2564: Property 't' has no initializer and is not definitely assigned in the constructor.
+
+
+==== inferenceFromGenericClassNoCrash1.ts (1 errors) ====
+    // https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576
+    
+    function RenderFlagsMixin<T extends new (...args: any[]) => object>(Base?: T) {}
+    class Container<T> {
+      t: T;
+      ~
+!!! error TS2564: Property 't' has no initializer and is not definitely assigned in the constructor.
+    }
+    RenderFlagsMixin(Container);
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/inferenceFromGenericClassNoCrash1.symbols b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.symbols
new file mode 100644
index 0000000000000..aa8dca0a91277
--- /dev/null
+++ b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.symbols
@@ -0,0 +1,24 @@
+//// [tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts] ////
+
+=== inferenceFromGenericClassNoCrash1.ts ===
+// https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576
+
+function RenderFlagsMixin<T extends new (...args: any[]) => object>(Base?: T) {}
+>RenderFlagsMixin : Symbol(RenderFlagsMixin, Decl(inferenceFromGenericClassNoCrash1.ts, 0, 0))
+>T : Symbol(T, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 26))
+>args : Symbol(args, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 41))
+>Base : Symbol(Base, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 68))
+>T : Symbol(T, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 26))
+
+class Container<T> {
+>Container : Symbol(Container, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 80))
+>T : Symbol(T, Decl(inferenceFromGenericClassNoCrash1.ts, 3, 16))
+
+  t: T;
+>t : Symbol(Container.t, Decl(inferenceFromGenericClassNoCrash1.ts, 3, 20))
+>T : Symbol(T, Decl(inferenceFromGenericClassNoCrash1.ts, 3, 16))
+}
+RenderFlagsMixin(Container);
+>RenderFlagsMixin : Symbol(RenderFlagsMixin, Decl(inferenceFromGenericClassNoCrash1.ts, 0, 0))
+>Container : Symbol(Container, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 80))
+
diff --git a/tests/baselines/reference/inferenceFromGenericClassNoCrash1.types b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.types
new file mode 100644
index 0000000000000..a3a0792e05780
--- /dev/null
+++ b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.types
@@ -0,0 +1,29 @@
+//// [tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts] ////
+
+=== inferenceFromGenericClassNoCrash1.ts ===
+// https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576
+
+function RenderFlagsMixin<T extends new (...args: any[]) => object>(Base?: T) {}
+>RenderFlagsMixin : <T extends new (...args: any[]) => object>(Base?: T) => void
+>                 : ^ ^^^^^^^^^                              ^^    ^^^ ^^^^^^^^^
+>args : any[]
+>     : ^^^^^
+>Base : T | undefined
+>     : ^^^^^^^^^^^^^
+
+class Container<T> {
+>Container : Container<T>
+>          : ^^^^^^^^^^^^
+
+  t: T;
+>t : T
+>  : ^
+}
+RenderFlagsMixin(Container);
+>RenderFlagsMixin(Container) : void
+>                            : ^^^^
+>RenderFlagsMixin : <T extends new (...args: any[]) => object>(Base?: T) => void
+>                 : ^ ^^^^^^^^^                              ^^    ^^^ ^^^^^^^^^
+>Container : typeof Container
+>          : ^^^^^^^^^^^^^^^^
+
diff --git a/tests/baselines/reference/nestedGenericSpreadInference.js b/tests/baselines/reference/nestedGenericSpreadInference.js
index 00bb4a558c2d4..b1d1fb9645e39 100644
--- a/tests/baselines/reference/nestedGenericSpreadInference.js
+++ b/tests/baselines/reference/nestedGenericSpreadInference.js
@@ -4,11 +4,9 @@
 declare function wrap<X>(x: X): { x: X };
 declare function call<A extends unknown[], T>(x: { x: (...args: A) => T }, ...args: A): T;
 
-// This should be of type `number` - ideally, it also would not error.
 const leak = call(wrap(<T>(x: T) => x), 1);
 
 
 //// [nestedGenericSpreadInference.js]
 "use strict";
-// This should be of type `number` - ideally, it also would not error.
 var leak = call(wrap(function (x) { return x; }), 1);
diff --git a/tests/baselines/reference/nestedGenericSpreadInference.symbols b/tests/baselines/reference/nestedGenericSpreadInference.symbols
index bef06547b70ec..ca6ba2f4361d5 100644
--- a/tests/baselines/reference/nestedGenericSpreadInference.symbols
+++ b/tests/baselines/reference/nestedGenericSpreadInference.symbols
@@ -22,13 +22,12 @@ declare function call<A extends unknown[], T>(x: { x: (...args: A) => T }, ...ar
 >A : Symbol(A, Decl(nestedGenericSpreadInference.ts, 1, 22))
 >T : Symbol(T, Decl(nestedGenericSpreadInference.ts, 1, 42))
 
-// This should be of type `number` - ideally, it also would not error.
 const leak = call(wrap(<T>(x: T) => x), 1);
->leak : Symbol(leak, Decl(nestedGenericSpreadInference.ts, 4, 5))
+>leak : Symbol(leak, Decl(nestedGenericSpreadInference.ts, 3, 5))
 >call : Symbol(call, Decl(nestedGenericSpreadInference.ts, 0, 41))
 >wrap : Symbol(wrap, Decl(nestedGenericSpreadInference.ts, 0, 0))
->T : Symbol(T, Decl(nestedGenericSpreadInference.ts, 4, 24))
->x : Symbol(x, Decl(nestedGenericSpreadInference.ts, 4, 27))
->T : Symbol(T, Decl(nestedGenericSpreadInference.ts, 4, 24))
->x : Symbol(x, Decl(nestedGenericSpreadInference.ts, 4, 27))
+>T : Symbol(T, Decl(nestedGenericSpreadInference.ts, 3, 24))
+>x : Symbol(x, Decl(nestedGenericSpreadInference.ts, 3, 27))
+>T : Symbol(T, Decl(nestedGenericSpreadInference.ts, 3, 24))
+>x : Symbol(x, Decl(nestedGenericSpreadInference.ts, 3, 27))
 
diff --git a/tests/baselines/reference/nestedGenericSpreadInference.types b/tests/baselines/reference/nestedGenericSpreadInference.types
index 1d13f4dd71d70..929a9cec916aa 100644
--- a/tests/baselines/reference/nestedGenericSpreadInference.types
+++ b/tests/baselines/reference/nestedGenericSpreadInference.types
@@ -21,16 +21,15 @@ declare function call<A extends unknown[], T>(x: { x: (...args: A) => T }, ...ar
 >args : A
 >     : ^
 
-// This should be of type `number` - ideally, it also would not error.
 const leak = call(wrap(<T>(x: T) => x), 1);
->leak : number
->     : ^^^^^^
->call(wrap(<T>(x: T) => x), 1) : number
->                              : ^^^^^^
+>leak : unknown
+>     : ^^^^^^^
+>call(wrap(<T>(x: T) => x), 1) : unknown
+>                              : ^^^^^^^
 >call : <A extends unknown[], T>(x: { x: (...args: A) => T; }, ...args: A) => T
 >     : ^ ^^^^^^^^^         ^^ ^^ ^^                         ^^^^^    ^^ ^^^^^ 
->wrap(<T>(x: T) => x) : { x: (x: A[0]) => A[0]; }
->                     : ^^^^^^ ^^^^^^^^^^^^^^^^^^
+>wrap(<T>(x: T) => x) : { x: (x: unknown) => unknown; }
+>                     : ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
 >wrap : <X>(x: X) => { x: X; }
 >     : ^ ^^ ^^ ^^^^^         
 ><T>(x: T) => x : <T>(x: T) => T
diff --git a/tests/baselines/reference/promisePermutations.types b/tests/baselines/reference/promisePermutations.types
index a752a677c0a4e..0c000ea24f39e 100644
--- a/tests/baselines/reference/promisePermutations.types
+++ b/tests/baselines/reference/promisePermutations.types
@@ -2,7 +2,7 @@
 
 === Performance Stats ===
 Type Count: 1,000 -> 2,500
-Instantiation count: 5,000 -> 10,000
+Instantiation count: 5,000
 
 === promisePermutations.ts ===
 interface Promise<T> {
diff --git a/tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts b/tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts
new file mode 100644
index 0000000000000..ff95031cbf728
--- /dev/null
+++ b/tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts
@@ -0,0 +1,59 @@
+// @strict: true
+// @noEmit: true
+
+// https://github.com/microsoft/TypeScript/issues/59937
+
+type Ref<T> = {
+  current: T;
+};
+
+type FunctionComponent<P> = (props: P) => unknown;
+
+type ComponentProps<T extends FunctionComponent<any>> =
+  T extends FunctionComponent<infer P> ? P : {};
+
+type PropsWithoutRef<P> = P extends any
+  ? "ref" extends keyof P
+    ? Omit<P, "ref">
+    : P
+  : P;
+
+type ComponentPropsWithoutRef<T extends FunctionComponent<any>> =
+  PropsWithoutRef<ComponentProps<T>>;
+
+declare function forwardRef<T, P>(
+  component: (props: P, ref: Ref<T>) => unknown,
+): (props: P & { ref?: Ref<T> }) => unknown;
+
+const ComponentWithForwardRef = forwardRef(
+  <T extends FunctionComponent<any>>(
+    props: ComponentPropsWithoutRef<T>,
+    ref: Ref<HTMLElement>,
+  ) => {
+    return null;
+  },
+);
+
+type Test<T> = T extends { component?: infer Component }
+  ? Component extends FunctionComponent<any>
+    ? ComponentProps<Component>
+    : never
+  : never;
+
+// the first one here has a chance to pollute the cache
+type Result1 = ComponentProps<typeof ComponentWithForwardRef>;
+// that could be incorrectly reused by this one
+type Result2 = Test<{ component: typeof ComponentWithForwardRef }>; // no `T` leak
+
+// same as ComponentWithForwardRef above but using a resolved signature instead of a direct inferred result of `forwardRef`
+declare const ComponentWithForwardRef2: <T extends FunctionComponent<any>>(
+  props: PropsWithoutRef<ComponentProps<T>> & {
+    className?: string;
+    as?: T | undefined;
+  } & {
+    ref?: Ref<HTMLElement> | undefined;
+  },
+) => unknown;
+
+type Result3 = ComponentProps<typeof ComponentWithForwardRef2>;
+type Result4 = Test<{ component: typeof ComponentWithForwardRef2 }>;
diff --git a/tests/cases/compiler/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts b/tests/cases/compiler/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts
new file mode 100644
index 0000000000000..5a7ca11d7905c
--- /dev/null
+++ b/tests/cases/compiler/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts
@@ -0,0 +1,46 @@
+// @strict: true
+// @noEmit: true
+
+declare const EffectTypeId: unique symbol;
+
+interface Variance<out A, out E, out R> {
+  readonly [EffectTypeId]: VarianceStruct<A, E, R>;
+}
+
+type Covariant<A> = (_: never) => A;
+
+interface VarianceStruct<out A, out E, out R> {
+  readonly _V: string;
+  readonly _A: Covariant<A>;
+  readonly _E: Covariant<E>;
+  readonly _R: Covariant<R>;
+}
+
+interface Effect<out A, out E = never, out R = never>
+  extends Variance<A, E, R> {}
+
+declare const succeed: <A>(value: A) => Effect<A>;
+
+type F<X, Y> = Y extends { _type: infer Z }
+  ? X extends Effect<infer A, infer E, infer R>
+    ? Effect<A, E, R | Z>
+    : X
+  : X;
+
+type ProxyMap<Service> = {
+  [K in keyof Service]: (Service & { _type: Service })[K];
+};
+
+declare const implement: <T>() => <I extends ReadonlyArray<any>, X>(
+  x: (...i: I) => X,
+) => (...i: I) => F<X, T>;
+
+class XXX {
+  log = implement<this>()(<N extends number>(n: N) => succeed(n));
+}
+
+export declare const inner: XXX;
+export declare const outer: ProxyMap<XXX>;
+
+export const a = inner.log(100); // Effect<100, never, never>
+export const b = outer.log(100); // Effect<100, never, XXX>
diff --git a/tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts b/tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts
index 1aff11c5b3507..57c14a76ba6f6 100644
--- a/tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts
+++ b/tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts
@@ -12,3 +12,18 @@ function withP2<P>(p: P) {
 
 const addP2 = withP2({ foo: 1 });
 const added2 = addP2({ bar: 2 });
+
+function withP3<P>(p: P) {
+  const m =
+    <I,>(from: I) =>
+    <I2,>(from2: I2) => ({ ...from, ...from2, ...p });
+  return createTransform(m);
+}
+
+const addP3 = withP3({ a: 1 });
+const addedSome3 = addP3({ b: '' });
+const added3 = addedSome3({ c: true });
+
+const addP3_other = withP3({ foo: 'bar' });
+const addedSome3_other = addP3_other({ qwerty: 123 });
+const added3_other = addedSome3_other({ bazinga: true });
diff --git a/tests/cases/compiler/genericCallWithinOwnBodyCastTypeParameterIdentity.ts b/tests/cases/compiler/genericCallWithinOwnBodyCastTypeParameterIdentity.ts
index 97058662ae75d..1358b238f7e00 100644
--- a/tests/cases/compiler/genericCallWithinOwnBodyCastTypeParameterIdentity.ts
+++ b/tests/cases/compiler/genericCallWithinOwnBodyCastTypeParameterIdentity.ts
@@ -1,4 +1,5 @@
 // @strict: true
+
 interface Thenable<Value> {
     then<V>(
         onFulfilled: (value: Value) => V | Thenable<V>,
diff --git a/tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts b/tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts
new file mode 100644
index 0000000000000..b8c0657f60823
--- /dev/null
+++ b/tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts
@@ -0,0 +1,10 @@
+// @strict: true
+// @noEmit: true
+
+// https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576
+
+function RenderFlagsMixin<T extends new (...args: any[]) => object>(Base?: T) {}
+class Container<T> {
+  t: T;
+}
+RenderFlagsMixin(Container);
diff --git a/tests/cases/compiler/nestedGenericSpreadInference.ts b/tests/cases/compiler/nestedGenericSpreadInference.ts
index 14e606f5f5cbf..fc3ea67d0ce6f 100644
--- a/tests/cases/compiler/nestedGenericSpreadInference.ts
+++ b/tests/cases/compiler/nestedGenericSpreadInference.ts
@@ -1,6 +1,6 @@
 // @strict: true
+
 declare function wrap<X>(x: X): { x: X };
 declare function call<A extends unknown[], T>(x: { x: (...args: A) => T }, ...args: A): T;
 
-// This should be of type `number` - ideally, it also would not error.
 const leak = call(wrap(<T>(x: T) => x), 1);