diff --git a/src/services/services.ts b/src/services/services.ts index 1c079b84027..08d3fc843ca 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3504,7 +3504,11 @@ namespace ts { // We don't want to complete using the type acquired by the shape // of the binding pattern; we are only interested in types acquired // through type declaration or inference. - if (rootDeclaration.initializer || rootDeclaration.type) { + // Also proceed if rootDeclaration is parameter and if its containing function expression\arrow function is contextually typed - + // type of parameter will flow in from the contextual type of the function + if (rootDeclaration.initializer || + rootDeclaration.type || + (rootDeclaration.kind === SyntaxKind.Parameter && isExpression(rootDeclaration.parent) && typeChecker.getContextualType(rootDeclaration.parent))) { typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer); existingMembers = (objectLikeContainer).elements; } diff --git a/tests/cases/fourslash/objectLiteralBindingInParameter.ts b/tests/cases/fourslash/objectLiteralBindingInParameter.ts new file mode 100644 index 00000000000..dfde6095bb9 --- /dev/null +++ b/tests/cases/fourslash/objectLiteralBindingInParameter.ts @@ -0,0 +1,15 @@ +/// + +////interface I { x1: number; x2: string } +////function f(cb: (ev: I) => any) { } +////f(({/*1*/}) => 0); + +////[null].reduce(({/*2*/}, b) => b); + +goTo.marker("1"); +verify.completionListContains("x1"); +verify.completionListContains("x2"); + +goTo.marker("2"); +verify.completionListContains("x1"); +verify.completionListContains("x2"); \ No newline at end of file