From 111b7c55f892817c728720f398502428d370154e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 17 Aug 2016 20:09:09 -0700 Subject: [PATCH 1/2] Added test. --- .../completionListInObjectLiteral4.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/cases/fourslash/completionListInObjectLiteral4.ts diff --git a/tests/cases/fourslash/completionListInObjectLiteral4.ts b/tests/cases/fourslash/completionListInObjectLiteral4.ts new file mode 100644 index 00000000000..c00462c8255 --- /dev/null +++ b/tests/cases/fourslash/completionListInObjectLiteral4.ts @@ -0,0 +1,28 @@ +/// + +// @strictNullChecks: true +////interface Thing { +//// hello: number; +//// world: string; +////} +//// +////declare function funcA(x : Thing): void; +////declare function funcB(x?: Thing): void; +////declare function funcC(x : Thing | null): void; +////declare function funcD(x : Thing | undefined): void; +////declare function funcE(x : Thing | null | undefined): void; +////declare function funcF(x?: Thing | null | undefined): void; +//// +////funcA({ /*A*/ }); +////funcB({ /*B*/ }); +////funcC({ /*C*/ }); +////funcD({ /*D*/ }); +////funcE({ /*E*/ }); +////funcF({ /*F*/ }); + + +for (const marker of test.markers()) { + goTo.position(marker.position); + verify.completionListContains("hello"); + verify.completionListContains("world"); +} From c1e70c97c066065fceade318af77e8b49f867dc7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 17 Aug 2016 20:32:52 -0700 Subject: [PATCH 2/2] Use the non-nullable type of the contextual type for object completions. --- src/services/services.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index ea85caf1332..9ef14315cb6 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3789,7 +3789,11 @@ namespace ts { // other than those within the declared type. isNewIdentifierLocation = true; + // If the object literal is being assigned to something of type 'null | { hello: string }', + // it clearly isn't trying to satisfy the 'null' type. So we grab the non-nullable type if possible. typeForObject = typeChecker.getContextualType(objectLikeContainer); + typeForObject = typeForObject && typeForObject.getNonNullableType(); + existingMembers = (objectLikeContainer).properties; } else if (objectLikeContainer.kind === SyntaxKind.ObjectBindingPattern) { @@ -3801,7 +3805,7 @@ 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. - // Also proceed if rootDeclaration is parameter and if its containing function expression\arrow function is contextually typed - + // Also proceed if rootDeclaration is a 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 let canGetType = !!(rootDeclaration.initializer || rootDeclaration.type); if (!canGetType && rootDeclaration.kind === SyntaxKind.Parameter) {