@@ -15632,6 +15632,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
15632
15632
);
15633
15633
}
15634
15634
15635
+ function getImplementationSignature(signature: Signature) {
15636
+ return signature.typeParameters ?
15637
+ signature.implementationSignatureCache ||= createImplementationSignature(signature) :
15638
+ signature;
15639
+ }
15640
+
15641
+ function createImplementationSignature(signature: Signature) {
15642
+ return signature.typeParameters ? instantiateSignature(signature, createTypeMapper([], [])) : signature;
15643
+ }
15644
+
15635
15645
function getBaseSignature(signature: Signature) {
15636
15646
const typeParameters = signature.typeParameters;
15637
15647
if (typeParameters) {
@@ -26364,9 +26374,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
26364
26374
// inference error only occurs when there are *conflicting* candidates, i.e.
26365
26375
// candidates with no common supertype.
26366
26376
const defaultType = getDefaultFromTypeParameter(inference.typeParameter);
26367
- // Instantiate the default type. Any forward reference to a type
26368
- // parameter should be instantiated to the empty object type.
26369
- inferredType = instantiateType(defaultType, mergeTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper));
26377
+ if (defaultType) {
26378
+ // Instantiate the default type. Any forward reference to a type
26379
+ // parameter should be instantiated to the empty object type.
26380
+ inferredType = instantiateType(defaultType, mergeTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper));
26381
+ }
26370
26382
}
26371
26383
}
26372
26384
else {
@@ -34867,7 +34879,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
34867
34879
}
34868
34880
34869
34881
for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
34870
- const candidate = candidates[candidateIndex];
34882
+ let candidate = candidates[candidateIndex];
34871
34883
if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
34872
34884
continue;
34873
34885
}
@@ -34876,6 +34888,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
34876
34888
let inferenceContext: InferenceContext | undefined;
34877
34889
34878
34890
if (candidate.typeParameters) {
34891
+ // If we are *inside the body of candidate*, we need to create a clone of `candidate` with differing type parameter identities,
34892
+ // so our inference results for this call doesn't pollute expression types referencing the outer type parameter!
34893
+ if (candidate.declaration && findAncestor(node, a => a === candidate.declaration)) {
34894
+ candidate = getImplementationSignature(candidate);
34895
+ }
34879
34896
let typeArgumentTypes: readonly Type[] | undefined;
34880
34897
if (some(typeArguments)) {
34881
34898
typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
@@ -34885,7 +34902,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
34885
34902
}
34886
34903
}
34887
34904
else {
34888
- inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
34905
+ inferenceContext = createInferenceContext(candidate.typeParameters! , candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
34889
34906
// The resulting type arguments are instantiated with the inference context mapper, as the inferred types may still contain references to the inference context's
34890
34907
// type variables via contextual projection. These are kept generic until all inferences are locked in, so the dependencies expressed can pass constraint checks.
34891
34908
typeArgumentTypes = instantiateTypes(inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext), inferenceContext.nonFixingMapper);
0 commit comments