Skip to content

Do not set valueDeclaration for intersection properties when one symbol does not have a valueDeclaration #61872

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15547,7 +15547,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
let firstValueDeclaration: Declaration | undefined;
let hasNonUniformValueDeclaration = false;
for (const prop of props) {
if (!firstValueDeclaration) {
if (!prop.valueDeclaration) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In isConflictingPrivateProperty, if symbols are not uniform and has private properties, determine property is conflict

    function isConflictingPrivateProperty(prop: Symbol) {
        // Return true for a synthetic property with multiple declarations, at least one of which is private.
        return !prop.valueDeclaration && !!(getCheckFlags(prop) & CheckFlags.ContainsPrivate);
    }

Currently, a intersection/uniform property is treated as uniform when one source property has a valueDeclaration, while another source property(mapped type) does not.
I think we should treat such properties as non-uniform instead.

hasNonUniformValueDeclaration = true;
}
else if (!firstValueDeclaration) {
firstValueDeclaration = prop.valueDeclaration;
}
else if (prop.valueDeclaration && prop.valueDeclaration !== firstValueDeclaration) {
Expand Down
10 changes: 10 additions & 0 deletions tests/baselines/reference/intersectionWithConflictingPrivates2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//// [tests/cases/compiler/intersectionWithConflictingPrivates2.ts] ////

//// [intersectionWithConflictingPrivates2.ts]
declare class A {
private a: number;

}
type B = Pick<{ a: number }, 'a'> & A;

//// [intersectionWithConflictingPrivates2.js]
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//// [tests/cases/compiler/intersectionWithConflictingPrivates2.ts] ////

=== intersectionWithConflictingPrivates2.ts ===
declare class A {
>A : Symbol(A, Decl(intersectionWithConflictingPrivates2.ts, 0, 0))

private a: number;
>a : Symbol(A.a, Decl(intersectionWithConflictingPrivates2.ts, 0, 17))

}
type B = Pick<{ a: number }, 'a'> & A;
>B : Symbol(B, Decl(intersectionWithConflictingPrivates2.ts, 3, 1))
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
>a : Symbol(a, Decl(intersectionWithConflictingPrivates2.ts, 4, 15))
>A : Symbol(A, Decl(intersectionWithConflictingPrivates2.ts, 0, 0))

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//// [tests/cases/compiler/intersectionWithConflictingPrivates2.ts] ////

=== intersectionWithConflictingPrivates2.ts ===
declare class A {
>A : A
> : ^

private a: number;
>a : number
> : ^^^^^^

}
type B = Pick<{ a: number }, 'a'> & A;
>B : never
> : ^^^^^
>a : number
> : ^^^^^^

5 changes: 5 additions & 0 deletions tests/cases/compiler/intersectionWithConflictingPrivates2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare class A {
private a: number;

}
type B = Pick<{ a: number }, 'a'> & A;