Skip to content

Commit 407edc9

Browse files
authored
fix(46563): show completions at this type (microsoft#46581)
1 parent c5d9200 commit 407edc9

File tree

9 files changed

+45
-5
lines changed

9 files changed

+45
-5
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ namespace ts {
432432
getIndexInfosOfType,
433433
getSignaturesOfType,
434434
getIndexTypeOfType: (type, kind) => getIndexTypeOfType(type, kind === IndexKind.String ? stringType : numberType),
435+
getIndexType: type => getIndexType(type),
435436
getBaseTypes,
436437
getBaseTypeOfLiteralType,
437438
getWidenedType,
@@ -15344,10 +15345,6 @@ namespace ts {
1534415345
(type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) && !isPatternLiteralType(type) ? ObjectFlags.IsGenericIndexType : 0);
1534515346
}
1534615347

15347-
function isThisTypeParameter(type: Type): boolean {
15348-
return !!(type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType);
15349-
}
15350-
1535115348
function getSimplifiedType(type: Type, writing: boolean): Type {
1535215349
return type.flags & TypeFlags.IndexedAccess ? getSimplifiedIndexedAccessType(type as IndexedAccessType, writing) :
1535315350
type.flags & TypeFlags.Conditional ? getSimplifiedConditionalType(type as ConditionalType, writing) :

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4162,6 +4162,7 @@ namespace ts {
41624162
getIndexInfosOfType(type: Type): readonly IndexInfo[];
41634163
getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[];
41644164
getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined;
4165+
/* @internal */ getIndexType(type: Type): Type;
41654166
getBaseTypes(type: InterfaceType): BaseType[];
41664167
getBaseTypeOfLiteralType(type: Type): Type;
41674168
getWidenedType(type: Type): Type;

src/compiler/utilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7414,4 +7414,8 @@ namespace ts {
74147414
export function escapeSnippetText(text: string): string {
74157415
return text.replace(/\$/gm, "\\$");
74167416
}
7417+
7418+
export function isThisTypeParameter(type: Type): boolean {
7419+
return !!(type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType);
7420+
}
74177421
}

src/services/services.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,9 @@ namespace ts {
500500
isClass(): this is InterfaceType {
501501
return !!(getObjectFlags(this) & ObjectFlags.Class);
502502
}
503+
isIndexType(): this is IndexType {
504+
return !!(this.flags & TypeFlags.Index);
505+
}
503506
/**
504507
* This polyfills `referenceType.typeArguments` for API consumers
505508
*/
@@ -545,6 +548,16 @@ namespace ts {
545548
getReturnType(): Type {
546549
return this.checker.getReturnTypeOfSignature(this);
547550
}
551+
getTypeParameterAtPosition(pos: number): Type {
552+
const type = this.checker.getParameterType(this, pos);
553+
if (type.isIndexType() && isThisTypeParameter(type.type)) {
554+
const constraint = type.type.getConstraint();
555+
if (constraint) {
556+
return this.checker.getIndexType(constraint);
557+
}
558+
}
559+
return type;
560+
}
548561

549562
getDocumentationComment(): SymbolDisplayPart[] {
550563
return this.documentationComment || (this.documentationComment = getDocumentationComment(singleElementArray(this.declaration), this.checker));

src/services/stringCompletions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ namespace ts.Completions.StringCompletions {
264264
checker.getResolvedSignature(argumentInfo.invocation, candidates, argumentInfo.argumentCount);
265265
const types = flatMap(candidates, candidate => {
266266
if (!signatureHasRestParameter(candidate) && argumentInfo.argumentCount > candidate.parameters.length) return;
267-
const type = checker.getParameterType(candidate, argumentInfo.argumentIndex);
267+
const type = candidate.getTypeParameterAtPosition(argumentInfo.argumentIndex);
268268
isNewIdentifier = isNewIdentifier || !!(type.flags & TypeFlags.String);
269269
return getStringLiteralTypes(type, uniques);
270270
});

src/services/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ namespace ts {
7272
isTypeParameter(): this is TypeParameter;
7373
isClassOrInterface(): this is InterfaceType;
7474
isClass(): this is InterfaceType;
75+
isIndexType(): this is IndexType;
7576
}
7677

7778
export interface TypeReference {
@@ -82,6 +83,7 @@ namespace ts {
8283
getDeclaration(): SignatureDeclaration;
8384
getTypeParameters(): TypeParameter[] | undefined;
8485
getParameters(): Symbol[];
86+
getTypeParameterAtPosition(pos: number): Type;
8587
getReturnType(): Type;
8688
getDocumentationComment(typeChecker: TypeChecker | undefined): SymbolDisplayPart[];
8789
getJsDocTags(): JSDocTagInfo[];

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5560,6 +5560,7 @@ declare namespace ts {
55605560
isTypeParameter(): this is TypeParameter;
55615561
isClassOrInterface(): this is InterfaceType;
55625562
isClass(): this is InterfaceType;
5563+
isIndexType(): this is IndexType;
55635564
}
55645565
interface TypeReference {
55655566
typeArguments?: readonly Type[];
@@ -5568,6 +5569,7 @@ declare namespace ts {
55685569
getDeclaration(): SignatureDeclaration;
55695570
getTypeParameters(): TypeParameter[] | undefined;
55705571
getParameters(): Symbol[];
5572+
getTypeParameterAtPosition(pos: number): Type;
55715573
getReturnType(): Type;
55725574
getDocumentationComment(typeChecker: TypeChecker | undefined): SymbolDisplayPart[];
55735575
getJsDocTags(): JSDocTagInfo[];

tests/baselines/reference/api/typescript.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5560,6 +5560,7 @@ declare namespace ts {
55605560
isTypeParameter(): this is TypeParameter;
55615561
isClassOrInterface(): this is InterfaceType;
55625562
isClass(): this is InterfaceType;
5563+
isIndexType(): this is IndexType;
55635564
}
55645565
interface TypeReference {
55655566
typeArguments?: readonly Type[];
@@ -5568,6 +5569,7 @@ declare namespace ts {
55685569
getDeclaration(): SignatureDeclaration;
55695570
getTypeParameters(): TypeParameter[] | undefined;
55705571
getParameters(): Symbol[];
5572+
getTypeParameterAtPosition(pos: number): Type;
55715573
getReturnType(): Type;
55725574
getDocumentationComment(typeChecker: TypeChecker | undefined): SymbolDisplayPart[];
55735575
getJsDocTags(): JSDocTagInfo[];
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
////class Test {
4+
//// foo() {}
5+
////
6+
//// bar() {
7+
//// this.baz(this, "/*1*/");
8+
////
9+
//// const t = new Test()
10+
//// this.baz(t, "/*2*/");
11+
//// }
12+
////
13+
//// baz<T>(a: T, k: keyof T) {}
14+
////}
15+
16+
verify.completions({
17+
marker: ["1", "2"],
18+
exact: ["foo", "bar", "baz"]
19+
});

0 commit comments

Comments
 (0)