Skip to content

Commit 279fec7

Browse files
committed
Merge pull request #7567 from Microsoft/contextual-type-parameters
show completion in destructured parameter if containing function was contextually typed
2 parents f0b3ff1 + 112e4b1 commit 279fec7

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

src/services/services.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3504,7 +3504,18 @@ namespace ts {
35043504
// We don't want to complete using the type acquired by the shape
35053505
// of the binding pattern; we are only interested in types acquired
35063506
// through type declaration or inference.
3507-
if (rootDeclaration.initializer || rootDeclaration.type) {
3507+
// Also proceed if rootDeclaration is parameter and if its containing function expression\arrow function is contextually typed -
3508+
// type of parameter will flow in from the contextual type of the function
3509+
let canGetType = !!(rootDeclaration.initializer || rootDeclaration.type);
3510+
if (!canGetType && rootDeclaration.kind === SyntaxKind.Parameter) {
3511+
if (isExpression(rootDeclaration.parent)) {
3512+
canGetType = !!typeChecker.getContextualType(<Expression>rootDeclaration.parent);
3513+
}
3514+
else if (rootDeclaration.parent.kind === SyntaxKind.MethodDeclaration || rootDeclaration.parent.kind === SyntaxKind.SetAccessor) {
3515+
canGetType = isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(<Expression>rootDeclaration.parent.parent);
3516+
}
3517+
}
3518+
if (canGetType) {
35083519
typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
35093520
existingMembers = (<BindingPattern>objectLikeContainer).elements;
35103521
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
////interface I { x1: number; x2: string }
4+
////function f(cb: (ev: I) => any) { }
5+
////f(({/*1*/}) => 0);
6+
7+
////[<I>null].reduce(({/*2*/}, b) => b);
8+
9+
////interface Foo {
10+
//// m(x: { x1: number, x2: number }): void;
11+
//// prop: I;
12+
////}
13+
////let x: Foo = {
14+
//// m({ /*3*/ }) {
15+
//// },
16+
//// get prop(): I { return undefined; },
17+
//// set prop({ /*4*/ }) {
18+
//// }
19+
////};
20+
21+
goTo.marker("1");
22+
verify.completionListContains("x1");
23+
verify.completionListContains("x2");
24+
25+
goTo.marker("2");
26+
verify.completionListContains("x1");
27+
verify.completionListContains("x2");
28+
29+
goTo.marker("3");
30+
verify.completionListContains("x1");
31+
verify.completionListContains("x2");
32+
33+
goTo.marker("4");
34+
verify.completionListContains("x1");
35+
verify.completionListContains("x2");

0 commit comments

Comments
 (0)