diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 7fcd96913ae06..3c2e75a2eb53b 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -30577,6 +30577,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
);
}
+ function filterContextualTypeForLiteralExpressionOfObject(node: Node, contextualType: Type) {
+ if (!isLiteralExpressionOfObject(node)) {
+ return contextualType;
+ }
+ return filterType(contextualType, t => {
+ if (!t.symbol || !(t.symbol.flags & SymbolFlags.Class)) {
+ return true;
+ }
+ return every(getPropertiesOfType(t), p => !p.valueDeclaration || !isNamedDeclaration(p.valueDeclaration) || (!isPrivateIdentifier(p.valueDeclaration.name) && !(getDeclarationModifierFlagsFromSymbol(p) & ModifierFlags.NonPublicAccessibilityModifier)));
+ });
+ }
+
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
// be "pushed" onto a node using the contextualType property.
function getApparentTypeOfContextualType(node: Expression | MethodDeclaration, contextFlags: ContextFlags | undefined): Type | undefined {
@@ -30671,6 +30683,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (index >= 0) {
return contextualTypes[index];
}
+ const contextualType = getContextualTypeWorker(node, contextFlags);
+ if (!contextualType) {
+ return undefined;
+ }
+ return filterContextualTypeForLiteralExpressionOfObject(node, contextualType);
+ }
+
+ function getContextualTypeWorker(node: Expression, contextFlags: ContextFlags | undefined): Type | undefined {
const { parent } = node;
switch (parent.kind) {
case SyntaxKind.VariableDeclaration:
@@ -38810,6 +38830,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function checkExpressionWithContextualType(node: Expression, contextualType: Type, inferenceContext: InferenceContext | undefined, checkMode: CheckMode): Type {
+ contextualType = filterContextualTypeForLiteralExpressionOfObject(node, contextualType);
const contextNode = getContextNode(node);
pushContextualType(contextNode, contextualType, /*isCache*/ false);
pushInferenceContext(contextNode, inferenceContext);
diff --git a/src/services/completions.ts b/src/services/completions.ts
index 155d048562b78..40ec73398878d 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -205,6 +205,7 @@ import {
isModifier,
isModifierKind,
isModuleDeclaration,
+ isNamedDeclaration,
isNamedExports,
isNamedImports,
isNamedImportsOrExports,
@@ -5401,7 +5402,7 @@ function getApparentProperties(type: Type, node: ObjectLiteralExpression | JsxAt
}
function containsNonPublicProperties(props: Symbol[]) {
- return some(props, p => !!(getDeclarationModifierFlagsFromSymbol(p) & ModifierFlags.NonPublicAccessibilityModifier));
+ return some(props, p => !!(getDeclarationModifierFlagsFromSymbol(p) & ModifierFlags.NonPublicAccessibilityModifier) || !!p.valueDeclaration && isNamedDeclaration(p.valueDeclaration) && isPrivateIdentifier(p.valueDeclaration.name));
}
/**
diff --git a/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.errors.txt b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.errors.txt
new file mode 100644
index 0000000000000..21d2b8fab2565
--- /dev/null
+++ b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.errors.txt
@@ -0,0 +1,41 @@
+contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts(18,8): error TS2345: Argument of type '{ doStuff: (arg: any) => void; }' is not assignable to parameter of type 'Foo'.
+ Property '#foo' is missing in type '{ doStuff: (arg: any) => void; }' but required in type 'Foo'.
+contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts(19,13): error TS7006: Parameter 'arg' implicitly has an 'any' type.
+
+
+==== contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts (2 errors) ====
+ class Foo {
+ #foo = "foo";
+ doStuff(cb: (arg: string) => void) {}
+ }
+
+ interface FooLike {
+ doStuff: (cb: (arg: number) => void) => void;
+ }
+
+ declare function useIt(arg: Foo | FooLike): void;
+
+ useIt({
+ doStuff: (arg) => {},
+ });
+
+ declare function useIt2(arg: Foo): void;
+
+ useIt2({
+ ~
+ doStuff: (arg) => {},
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ ~~~
+!!! error TS7006: Parameter 'arg' implicitly has an 'any' type.
+ });
+ ~
+!!! error TS2345: Argument of type '{ doStuff: (arg: any) => void; }' is not assignable to parameter of type 'Foo'.
+!!! error TS2345: Property '#foo' is missing in type '{ doStuff: (arg: any) => void; }' but required in type 'Foo'.
+!!! related TS2728 contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts:2:3: '#foo' is declared here.
+
+ declare function useIt3(arg: FooLike): void;
+
+ useIt3({
+ doStuff: (arg) => {},
+ });
+
\ No newline at end of file
diff --git a/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.symbols b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.symbols
new file mode 100644
index 0000000000000..bf2b4e64da5da
--- /dev/null
+++ b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.symbols
@@ -0,0 +1,67 @@
+//// [tests/cases/compiler/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts] ////
+
+=== contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts ===
+class Foo {
+>Foo : Symbol(Foo, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 0, 0))
+
+ #foo = "foo";
+>#foo : Symbol(Foo.#foo, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 0, 11))
+
+ doStuff(cb: (arg: string) => void) {}
+>doStuff : Symbol(Foo.doStuff, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 1, 15))
+>cb : Symbol(cb, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 2, 10))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 2, 15))
+}
+
+interface FooLike {
+>FooLike : Symbol(FooLike, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 3, 1))
+
+ doStuff: (cb: (arg: number) => void) => void;
+>doStuff : Symbol(FooLike.doStuff, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 5, 19))
+>cb : Symbol(cb, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 6, 12))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 6, 17))
+}
+
+declare function useIt(arg: Foo | FooLike): void;
+>useIt : Symbol(useIt, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 7, 1))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 9, 23))
+>Foo : Symbol(Foo, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 0, 0))
+>FooLike : Symbol(FooLike, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 3, 1))
+
+useIt({
+>useIt : Symbol(useIt, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 7, 1))
+
+ doStuff: (arg) => {},
+>doStuff : Symbol(doStuff, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 11, 7))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 12, 12))
+
+});
+
+declare function useIt2(arg: Foo): void;
+>useIt2 : Symbol(useIt2, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 13, 3))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 15, 24))
+>Foo : Symbol(Foo, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 0, 0))
+
+useIt2({
+>useIt2 : Symbol(useIt2, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 13, 3))
+
+ doStuff: (arg) => {},
+>doStuff : Symbol(doStuff, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 17, 8))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 18, 12))
+
+});
+
+declare function useIt3(arg: FooLike): void;
+>useIt3 : Symbol(useIt3, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 19, 3))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 21, 24))
+>FooLike : Symbol(FooLike, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 3, 1))
+
+useIt3({
+>useIt3 : Symbol(useIt3, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 19, 3))
+
+ doStuff: (arg) => {},
+>doStuff : Symbol(doStuff, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 23, 8))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts, 24, 12))
+
+});
+
diff --git a/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.types b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.types
new file mode 100644
index 0000000000000..c9afc7fbcb03a
--- /dev/null
+++ b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.types
@@ -0,0 +1,71 @@
+//// [tests/cases/compiler/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts] ////
+
+=== contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts ===
+class Foo {
+>Foo : Foo
+
+ #foo = "foo";
+>#foo : string
+>"foo" : "foo"
+
+ doStuff(cb: (arg: string) => void) {}
+>doStuff : (cb: (arg: string) => void) => void
+>cb : (arg: string) => void
+>arg : string
+}
+
+interface FooLike {
+ doStuff: (cb: (arg: number) => void) => void;
+>doStuff : (cb: (arg: number) => void) => void
+>cb : (arg: number) => void
+>arg : number
+}
+
+declare function useIt(arg: Foo | FooLike): void;
+>useIt : (arg: Foo | FooLike) => void
+>arg : Foo | FooLike
+
+useIt({
+>useIt({ doStuff: (arg) => {},}) : void
+>useIt : (arg: Foo | FooLike) => void
+>{ doStuff: (arg) => {},} : { doStuff: (arg: (arg: number) => void) => void; }
+
+ doStuff: (arg) => {},
+>doStuff : (arg: (arg: number) => void) => void
+>(arg) => {} : (arg: (arg: number) => void) => void
+>arg : (arg: number) => void
+
+});
+
+declare function useIt2(arg: Foo): void;
+>useIt2 : (arg: Foo) => void
+>arg : Foo
+
+useIt2({
+>useIt2({ doStuff: (arg) => {},}) : void
+>useIt2 : (arg: Foo) => void
+>{ doStuff: (arg) => {},} : { doStuff: (arg: any) => void; }
+
+ doStuff: (arg) => {},
+>doStuff : (arg: any) => void
+>(arg) => {} : (arg: any) => void
+>arg : any
+
+});
+
+declare function useIt3(arg: FooLike): void;
+>useIt3 : (arg: FooLike) => void
+>arg : FooLike
+
+useIt3({
+>useIt3({ doStuff: (arg) => {},}) : void
+>useIt3 : (arg: FooLike) => void
+>{ doStuff: (arg) => {},} : { doStuff: (arg: (arg: number) => void) => void; }
+
+ doStuff: (arg) => {},
+>doStuff : (arg: (arg: number) => void) => void
+>(arg) => {} : (arg: (arg: number) => void) => void
+>arg : (arg: number) => void
+
+});
+
diff --git a/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.errors.txt b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.errors.txt
new file mode 100644
index 0000000000000..b4a2d1a5a5114
--- /dev/null
+++ b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.errors.txt
@@ -0,0 +1,41 @@
+contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts(18,8): error TS2345: Argument of type '{ doStuff: (arg: any) => void; }' is not assignable to parameter of type 'Foo'.
+ Property 'foo' is missing in type '{ doStuff: (arg: any) => void; }' but required in type 'Foo'.
+contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts(19,13): error TS7006: Parameter 'arg' implicitly has an 'any' type.
+
+
+==== contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts (2 errors) ====
+ class Foo {
+ private foo = "foo";
+ doStuff(cb: (arg: string) => void) {}
+ }
+
+ interface FooLike {
+ doStuff: (cb: (arg: number) => void) => void;
+ }
+
+ declare function useIt(arg: Foo | FooLike): void;
+
+ useIt({
+ doStuff: (arg) => {},
+ });
+
+ declare function useIt2(arg: Foo): void;
+
+ useIt2({
+ ~
+ doStuff: (arg) => {},
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ ~~~
+!!! error TS7006: Parameter 'arg' implicitly has an 'any' type.
+ });
+ ~
+!!! error TS2345: Argument of type '{ doStuff: (arg: any) => void; }' is not assignable to parameter of type 'Foo'.
+!!! error TS2345: Property 'foo' is missing in type '{ doStuff: (arg: any) => void; }' but required in type 'Foo'.
+!!! related TS2728 contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts:2:11: 'foo' is declared here.
+
+ declare function useIt3(arg: FooLike): void;
+
+ useIt3({
+ doStuff: (arg) => {},
+ });
+
\ No newline at end of file
diff --git a/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.symbols b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.symbols
new file mode 100644
index 0000000000000..f0e4b7df8f065
--- /dev/null
+++ b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.symbols
@@ -0,0 +1,67 @@
+//// [tests/cases/compiler/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts] ////
+
+=== contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts ===
+class Foo {
+>Foo : Symbol(Foo, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 0, 0))
+
+ private foo = "foo";
+>foo : Symbol(Foo.foo, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 0, 11))
+
+ doStuff(cb: (arg: string) => void) {}
+>doStuff : Symbol(Foo.doStuff, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 1, 22))
+>cb : Symbol(cb, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 2, 10))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 2, 15))
+}
+
+interface FooLike {
+>FooLike : Symbol(FooLike, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 3, 1))
+
+ doStuff: (cb: (arg: number) => void) => void;
+>doStuff : Symbol(FooLike.doStuff, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 5, 19))
+>cb : Symbol(cb, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 6, 12))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 6, 17))
+}
+
+declare function useIt(arg: Foo | FooLike): void;
+>useIt : Symbol(useIt, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 7, 1))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 9, 23))
+>Foo : Symbol(Foo, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 0, 0))
+>FooLike : Symbol(FooLike, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 3, 1))
+
+useIt({
+>useIt : Symbol(useIt, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 7, 1))
+
+ doStuff: (arg) => {},
+>doStuff : Symbol(doStuff, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 11, 7))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 12, 12))
+
+});
+
+declare function useIt2(arg: Foo): void;
+>useIt2 : Symbol(useIt2, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 13, 3))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 15, 24))
+>Foo : Symbol(Foo, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 0, 0))
+
+useIt2({
+>useIt2 : Symbol(useIt2, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 13, 3))
+
+ doStuff: (arg) => {},
+>doStuff : Symbol(doStuff, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 17, 8))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 18, 12))
+
+});
+
+declare function useIt3(arg: FooLike): void;
+>useIt3 : Symbol(useIt3, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 19, 3))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 21, 24))
+>FooLike : Symbol(FooLike, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 3, 1))
+
+useIt3({
+>useIt3 : Symbol(useIt3, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 19, 3))
+
+ doStuff: (arg) => {},
+>doStuff : Symbol(doStuff, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 23, 8))
+>arg : Symbol(arg, Decl(contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts, 24, 12))
+
+});
+
diff --git a/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.types b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.types
new file mode 100644
index 0000000000000..eed41173a89e7
--- /dev/null
+++ b/tests/baselines/reference/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.types
@@ -0,0 +1,71 @@
+//// [tests/cases/compiler/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts] ////
+
+=== contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts ===
+class Foo {
+>Foo : Foo
+
+ private foo = "foo";
+>foo : string
+>"foo" : "foo"
+
+ doStuff(cb: (arg: string) => void) {}
+>doStuff : (cb: (arg: string) => void) => void
+>cb : (arg: string) => void
+>arg : string
+}
+
+interface FooLike {
+ doStuff: (cb: (arg: number) => void) => void;
+>doStuff : (cb: (arg: number) => void) => void
+>cb : (arg: number) => void
+>arg : number
+}
+
+declare function useIt(arg: Foo | FooLike): void;
+>useIt : (arg: Foo | FooLike) => void
+>arg : Foo | FooLike
+
+useIt({
+>useIt({ doStuff: (arg) => {},}) : void
+>useIt : (arg: Foo | FooLike) => void
+>{ doStuff: (arg) => {},} : { doStuff: (arg: (arg: number) => void) => void; }
+
+ doStuff: (arg) => {},
+>doStuff : (arg: (arg: number) => void) => void
+>(arg) => {} : (arg: (arg: number) => void) => void
+>arg : (arg: number) => void
+
+});
+
+declare function useIt2(arg: Foo): void;
+>useIt2 : (arg: Foo) => void
+>arg : Foo
+
+useIt2({
+>useIt2({ doStuff: (arg) => {},}) : void
+>useIt2 : (arg: Foo) => void
+>{ doStuff: (arg) => {},} : { doStuff: (arg: any) => void; }
+
+ doStuff: (arg) => {},
+>doStuff : (arg: any) => void
+>(arg) => {} : (arg: any) => void
+>arg : any
+
+});
+
+declare function useIt3(arg: FooLike): void;
+>useIt3 : (arg: FooLike) => void
+>arg : FooLike
+
+useIt3({
+>useIt3({ doStuff: (arg) => {},}) : void
+>useIt3 : (arg: FooLike) => void
+>{ doStuff: (arg) => {},} : { doStuff: (arg: (arg: number) => void) => void; }
+
+ doStuff: (arg) => {},
+>doStuff : (arg: (arg: number) => void) => void
+>(arg) => {} : (arg: (arg: number) => void) => void
+>arg : (arg: number) => void
+
+});
+
diff --git a/tests/cases/compiler/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts b/tests/cases/compiler/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts
new file mode 100644
index 0000000000000..19ccc3db67174
--- /dev/null
+++ b/tests/cases/compiler/contextuallyTypedParametersPositionIncludesClassWithPrivateMember1.ts
@@ -0,0 +1,30 @@
+// @strict: true
+// @target: esnext
+// @noEmit: true
+
+class Foo {
+ #foo = "foo";
+ doStuff(cb: (arg: string) => void) {}
+}
+
+interface FooLike {
+ doStuff: (cb: (arg: number) => void) => void;
+}
+
+declare function useIt(arg: Foo | FooLike): void;
+
+useIt({
+ doStuff: (arg) => {},
+});
+
+declare function useIt2(arg: Foo): void;
+
+useIt2({
+ doStuff: (arg) => {},
+});
+
+declare function useIt3(arg: FooLike): void;
+
+useIt3({
+ doStuff: (arg) => {},
+});
diff --git a/tests/cases/compiler/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts b/tests/cases/compiler/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts
new file mode 100644
index 0000000000000..d985d05f3900c
--- /dev/null
+++ b/tests/cases/compiler/contextuallyTypedParametersPositionIncludesClassWithPrivateMember2.ts
@@ -0,0 +1,29 @@
+// @strict: true
+// @noEmit: true
+
+class Foo {
+ private foo = "foo";
+ doStuff(cb: (arg: string) => void) {}
+}
+
+interface FooLike {
+ doStuff: (cb: (arg: number) => void) => void;
+}
+
+declare function useIt(arg: Foo | FooLike): void;
+
+useIt({
+ doStuff: (arg) => {},
+});
+
+declare function useIt2(arg: Foo): void;
+
+useIt2({
+ doStuff: (arg) => {},
+});
+
+declare function useIt3(arg: FooLike): void;
+
+useIt3({
+ doStuff: (arg) => {},
+});
diff --git a/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember1.ts b/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember1.ts
new file mode 100644
index 0000000000000..ce7898246075e
--- /dev/null
+++ b/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember1.ts
@@ -0,0 +1,37 @@
+///
+
+// @strict: true
+
+//// type ExampleInit = {
+//// foo: number;
+//// };
+////
+//// type ExampleLike = Example | ExampleInit;
+////
+//// class Example {
+//// static isExample(value: any): value is Example {
+//// return #foo in value;
+//// }
+////
+//// static from(exampleLike: ExampleLike): Example {
+//// if (Example.isExample(exampleLike)) {
+//// return exampleLike;
+//// }
+//// return new Example(exampleLike);
+//// }
+////
+//// readonly #foo: number;
+////
+//// constructor({ foo }: ExampleInit) {
+//// this.#foo = foo;
+//// }
+//// }
+////
+//// const example = Example.from({
+//// /*1*/
+//// });
+
+verify.completions({
+ marker: "1",
+ exact: ["foo"]
+})
diff --git a/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember2.ts b/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember2.ts
new file mode 100644
index 0000000000000..47a91fc3b1d41
--- /dev/null
+++ b/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember2.ts
@@ -0,0 +1,37 @@
+///
+
+// @strict: true
+
+//// type ExampleInit = {
+//// foo: number;
+//// };
+////
+//// type ExampleLike = Example | ExampleInit;
+////
+//// class Example {
+//// static isExample(value: any): value is Example {
+//// return #foo in value;
+//// }
+////
+//// static from({ exampleLike }: { exampleLike: ExampleLike }): Example {
+//// if (Example.isExample(exampleLike)) {
+//// return exampleLike;
+//// }
+//// return new Example(exampleLike);
+//// }
+////
+//// readonly #foo: number;
+////
+//// constructor({ foo }: ExampleInit) {
+//// this.#foo = foo;
+//// }
+//// }
+////
+//// const example = Example.from({
+//// exampleLike: { /*1*/ },
+//// });
+
+verify.completions({
+ marker: "1",
+ exact: ["foo"]
+})
diff --git a/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember3.ts b/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember3.ts
new file mode 100644
index 0000000000000..8c178d3f4cd9a
--- /dev/null
+++ b/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember3.ts
@@ -0,0 +1,37 @@
+///
+
+// @strict: true
+
+//// type ExampleInit = {
+//// foo: number;
+//// };
+////
+//// type ExampleLike = Example | ExampleInit;
+////
+//// class Example {
+//// static isExample(value: any): value is Example {
+//// return 'bar' in value;
+//// }
+////
+//// static from(exampleLike: ExampleLike): Example {
+//// if (Example.isExample(exampleLike)) {
+//// return exampleLike;
+//// }
+//// return new Example(exampleLike);
+//// }
+////
+//// private bar: number;
+////
+//// constructor({ foo }: ExampleInit) {
+//// this.bar = foo;
+//// }
+//// }
+////
+//// const example = Example.from({
+//// /*1*/
+//// });
+
+verify.completions({
+ marker: "1",
+ exact: ["foo"]
+})
diff --git a/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember4.ts b/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember4.ts
new file mode 100644
index 0000000000000..8bb0f9dc73fb1
--- /dev/null
+++ b/tests/cases/fourslash/completionsObjectLiteralPositionIncludesClassWithPrivateMember4.ts
@@ -0,0 +1,37 @@
+///
+
+// @strict: true
+
+//// type ExampleInit = {
+//// foo: number;
+//// };
+////
+//// type ExampleLike = Example | ExampleInit;
+////
+//// class Example {
+//// static isExample(value: any): value is Example {
+//// return 'bar' in value;
+//// }
+////
+//// static from({ exampleLike }: { exampleLike: ExampleLike }): Example {
+//// if (Example.isExample(exampleLike)) {
+//// return exampleLike;
+//// }
+//// return new Example(exampleLike);
+//// }
+////
+//// private bar: number;
+////
+//// constructor({ foo }: ExampleInit) {
+//// this.bar = foo;
+//// }
+//// }
+////
+//// const example = Example.from({
+//// exampleLike: { /*1*/ },
+//// });
+
+verify.completions({
+ marker: "1",
+ exact: ["foo"]
+})