Skip to content

Commit a138985

Browse files
author
Andy
authored
isValidMethodAccess: Instantiate signature this type if necessary (#21722)
1 parent e5f91f5 commit a138985

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

src/compiler/checker.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6959,7 +6959,10 @@ namespace ts {
69596959
}
69606960

69616961
function createSignatureInstantiation(signature: Signature, typeArguments: Type[]): Signature {
6962-
return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), /*eraseTypeParameters*/ true);
6962+
return instantiateSignature(signature, createSignatureTypeMapper(signature, typeArguments), /*eraseTypeParameters*/ true);
6963+
}
6964+
function createSignatureTypeMapper(signature: Signature, typeArguments: Type[]): TypeMapper {
6965+
return createTypeMapper(signature.typeParameters, typeArguments);
69636966
}
69646967

69656968
function getErasedSignature(signature: Signature): Signature {
@@ -11419,8 +11422,8 @@ namespace ts {
1141911422
}
1142011423
}
1142111424

11422-
function createInferenceContext(typeParameters: TypeParameter[], signature: Signature, flags: InferenceFlags, compareTypes?: TypeComparer, baseInferences?: InferenceInfo[]): InferenceContext {
11423-
const inferences = baseInferences ? map(baseInferences, cloneInferenceInfo) : map(typeParameters, createInferenceInfo);
11425+
function createInferenceContext(typeParameters: TypeParameter[], signature: Signature | undefined, flags: InferenceFlags, compareTypes?: TypeComparer, baseInferences?: InferenceInfo[]): InferenceContext {
11426+
const inferences = baseInferences ? baseInferences.map(cloneInferenceInfo) : typeParameters.map(createInferenceInfo);
1142411427
const context = mapper as InferenceContext;
1142511428
context.typeParameters = typeParameters;
1142611429
context.signature = signature;
@@ -16409,15 +16412,23 @@ namespace ts {
1640916412
return isValidPropertyAccessWithType(node, node.expression, property.escapedName, type)
1641016413
&& (!(property.flags & SymbolFlags.Method) || isValidMethodAccess(property, type));
1641116414
}
16412-
function isValidMethodAccess(method: Symbol, type: Type) {
16415+
function isValidMethodAccess(method: Symbol, actualThisType: Type): boolean {
1641316416
const propType = getTypeOfFuncClassEnumModule(method);
1641416417
const signatures = getSignaturesOfType(getNonNullableType(propType), SignatureKind.Call);
1641516418
Debug.assert(signatures.length !== 0);
1641616419
return signatures.some(sig => {
16417-
const thisType = getThisTypeOfSignature(sig);
16418-
return !thisType || isTypeAssignableTo(type, thisType);
16420+
const signatureThisType = getThisTypeOfSignature(sig);
16421+
return !signatureThisType || isTypeAssignableTo(actualThisType, getInstantiatedSignatureThisType(sig, signatureThisType, actualThisType));
1641916422
});
1642016423
}
16424+
function getInstantiatedSignatureThisType(sig: Signature, signatureThisType: Type, actualThisType: Type): Type {
16425+
if (!sig.typeParameters) {
16426+
return signatureThisType;
16427+
}
16428+
const context = createInferenceContext(sig.typeParameters, sig, InferenceFlags.None);
16429+
inferTypes(context.inferences, actualThisType, signatureThisType);
16430+
return instantiateType(signatureThisType, createSignatureTypeMapper(sig, getInferredTypes(context)));
16431+
}
1642116432

1642216433
function isValidPropertyAccessWithType(
1642316434
node: PropertyAccessExpression | QualifiedName,

tests/cases/fourslash/completionsMethodWithThisParameter.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
//// value: T; // Make the type parameter actually matter
55
//// ms(this: A<string>) {}
66
//// mo(this: A<{}>) {}
7+
//// mp<P>(this: A<P>) {}
8+
//// mps<P extends string>(this: A<P>) {}
79
////}
810
////
911
////const s = new A<string>();
1012
////const n = new A<number>();
1113
////s./*s*/;
1214
////n./*n*/;
1315

14-
verify.completionsAt("s", ["value", "ms", "mo"]);
15-
verify.completionsAt("n", ["value", "mo"]);
16+
verify.completionsAt("s", ["value", "ms", "mo", "mp", "mps"]);
17+
verify.completionsAt("n", ["value", "mo", "mp"]);

0 commit comments

Comments
 (0)