Skip to content

Commit 3b2fa50

Browse files
authored
fix(48487): allow using private names as the self-assignment entity name (microsoft#48496)
1 parent b1fb729 commit 3b2fa50

9 files changed

+216
-7
lines changed

src/compiler/utilities.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -2338,18 +2338,13 @@ namespace ts {
23382338
if (isPropertyNameLiteral(name) && isPropertyNameLiteral(initializer)) {
23392339
return getTextOfIdentifierOrLiteral(name) === getTextOfIdentifierOrLiteral(initializer);
23402340
}
2341-
if (isIdentifier(name) && isLiteralLikeAccess(initializer) &&
2341+
if (isMemberName(name) && isLiteralLikeAccess(initializer) &&
23422342
(initializer.expression.kind === SyntaxKind.ThisKeyword ||
23432343
isIdentifier(initializer.expression) &&
23442344
(initializer.expression.escapedText === "window" ||
23452345
initializer.expression.escapedText === "self" ||
23462346
initializer.expression.escapedText === "global"))) {
2347-
2348-
const nameOrArgument = getNameOrArgument(initializer);
2349-
if (isPrivateIdentifier(nameOrArgument)) {
2350-
Debug.fail("Unexpected PrivateIdentifier in name expression with literal-like access.");
2351-
}
2352-
return isSameEntityName(name, nameOrArgument);
2347+
return isSameEntityName(name, getNameOrArgument(initializer));
23532348
}
23542349
if (isLiteralLikeAccess(name) && isLiteralLikeAccess(initializer)) {
23552350
return getElementOrPropertyAccessName(name) === getElementOrPropertyAccessName(initializer)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [typeFromPrivatePropertyAssignment.ts]
2+
type Foo = { foo?: string };
3+
4+
class C {
5+
#a?: Foo;
6+
#b?: Foo;
7+
8+
m() {
9+
const a = this.#a || {};
10+
this.#b = this.#b || {};
11+
}
12+
}
13+
14+
15+
//// [typeFromPrivatePropertyAssignment.js]
16+
class C {
17+
#a;
18+
#b;
19+
m() {
20+
const a = this.#a || {};
21+
this.#b = this.#b || {};
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
=== tests/cases/conformance/classes/members/privateNames/typeFromPrivatePropertyAssignment.ts ===
2+
type Foo = { foo?: string };
3+
>Foo : Symbol(Foo, Decl(typeFromPrivatePropertyAssignment.ts, 0, 0))
4+
>foo : Symbol(foo, Decl(typeFromPrivatePropertyAssignment.ts, 0, 12))
5+
6+
class C {
7+
>C : Symbol(C, Decl(typeFromPrivatePropertyAssignment.ts, 0, 28))
8+
9+
#a?: Foo;
10+
>#a : Symbol(C.#a, Decl(typeFromPrivatePropertyAssignment.ts, 2, 9))
11+
>Foo : Symbol(Foo, Decl(typeFromPrivatePropertyAssignment.ts, 0, 0))
12+
13+
#b?: Foo;
14+
>#b : Symbol(C.#b, Decl(typeFromPrivatePropertyAssignment.ts, 3, 13))
15+
>Foo : Symbol(Foo, Decl(typeFromPrivatePropertyAssignment.ts, 0, 0))
16+
17+
m() {
18+
>m : Symbol(C.m, Decl(typeFromPrivatePropertyAssignment.ts, 4, 13))
19+
20+
const a = this.#a || {};
21+
>a : Symbol(a, Decl(typeFromPrivatePropertyAssignment.ts, 7, 13))
22+
>this.#a : Symbol(C.#a, Decl(typeFromPrivatePropertyAssignment.ts, 2, 9))
23+
>this : Symbol(C, Decl(typeFromPrivatePropertyAssignment.ts, 0, 28))
24+
25+
this.#b = this.#b || {};
26+
>this.#b : Symbol(C.#b, Decl(typeFromPrivatePropertyAssignment.ts, 3, 13))
27+
>this : Symbol(C, Decl(typeFromPrivatePropertyAssignment.ts, 0, 28))
28+
>this.#b : Symbol(C.#b, Decl(typeFromPrivatePropertyAssignment.ts, 3, 13))
29+
>this : Symbol(C, Decl(typeFromPrivatePropertyAssignment.ts, 0, 28))
30+
}
31+
}
32+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
=== tests/cases/conformance/classes/members/privateNames/typeFromPrivatePropertyAssignment.ts ===
2+
type Foo = { foo?: string };
3+
>Foo : Foo
4+
>foo : string
5+
6+
class C {
7+
>C : C
8+
9+
#a?: Foo;
10+
>#a : Foo
11+
12+
#b?: Foo;
13+
>#b : Foo
14+
15+
m() {
16+
>m : () => void
17+
18+
const a = this.#a || {};
19+
>a : Foo
20+
>this.#a || {} : Foo
21+
>this.#a : Foo
22+
>this : this
23+
>{} : {}
24+
25+
this.#b = this.#b || {};
26+
>this.#b = this.#b || {} : Foo
27+
>this.#b : Foo
28+
>this : this
29+
>this.#b || {} : Foo
30+
>this.#b : Foo
31+
>this : this
32+
>{} : {}
33+
}
34+
}
35+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//// [tests/cases/conformance/classes/members/privateNames/typeFromPrivatePropertyAssignmentJs.ts] ////
2+
3+
//// [typeFromPrivatePropertyAssignmentJs.js]
4+
5+
//// [a.js]
6+
class C {
7+
/** @type {{ foo?: string } | undefined } */
8+
#a;
9+
/** @type {{ foo?: string } | undefined } */
10+
#b;
11+
m() {
12+
const a = this.#a || {};
13+
this.#b = this.#b || {};
14+
}
15+
}
16+
17+
18+
//// [typeFromPrivatePropertyAssignmentJs.js]
19+
//// [a.js]
20+
class C {
21+
/** @type {{ foo?: string } | undefined } */
22+
#a;
23+
/** @type {{ foo?: string } | undefined } */
24+
#b;
25+
m() {
26+
const a = this.#a || {};
27+
this.#b = this.#b || {};
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
=== tests/cases/conformance/classes/members/privateNames/typeFromPrivatePropertyAssignmentJs.js ===
2+
3+
No type information for this code.=== tests/cases/conformance/classes/members/privateNames/a.js ===
4+
class C {
5+
>C : Symbol(C, Decl(a.js, 0, 0))
6+
7+
/** @type {{ foo?: string } | undefined } */
8+
#a;
9+
>#a : Symbol(C.#a, Decl(a.js, 0, 9))
10+
11+
/** @type {{ foo?: string } | undefined } */
12+
#b;
13+
>#b : Symbol(C.#b, Decl(a.js, 2, 7))
14+
15+
m() {
16+
>m : Symbol(C.m, Decl(a.js, 4, 7))
17+
18+
const a = this.#a || {};
19+
>a : Symbol(a, Decl(a.js, 6, 13))
20+
>this.#a : Symbol(C.#a, Decl(a.js, 0, 9))
21+
>this : Symbol(C, Decl(a.js, 0, 0))
22+
23+
this.#b = this.#b || {};
24+
>this.#b : Symbol(C.#b, Decl(a.js, 2, 7))
25+
>this : Symbol(C, Decl(a.js, 0, 0))
26+
>this.#b : Symbol(C.#b, Decl(a.js, 2, 7))
27+
>this : Symbol(C, Decl(a.js, 0, 0))
28+
}
29+
}
30+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
=== tests/cases/conformance/classes/members/privateNames/typeFromPrivatePropertyAssignmentJs.js ===
2+
3+
No type information for this code.=== tests/cases/conformance/classes/members/privateNames/a.js ===
4+
class C {
5+
>C : C
6+
7+
/** @type {{ foo?: string } | undefined } */
8+
#a;
9+
>#a : { foo?: string; }
10+
11+
/** @type {{ foo?: string } | undefined } */
12+
#b;
13+
>#b : { foo?: string; }
14+
15+
m() {
16+
>m : () => void
17+
18+
const a = this.#a || {};
19+
>a : { foo?: string; }
20+
>this.#a || {} : { foo?: string; }
21+
>this.#a : { foo?: string; }
22+
>this : this
23+
>{} : {}
24+
25+
this.#b = this.#b || {};
26+
>this.#b = this.#b || {} : { foo?: string; }
27+
>this.#b : { foo?: string; }
28+
>this : this
29+
>this.#b || {} : { foo?: string; }
30+
>this.#b : { foo?: string; }
31+
>this : this
32+
>{} : {}
33+
}
34+
}
35+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// @target: esnext
2+
3+
type Foo = { foo?: string };
4+
5+
class C {
6+
#a?: Foo;
7+
#b?: Foo;
8+
9+
m() {
10+
const a = this.#a || {};
11+
this.#b = this.#b || {};
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// @target: esnext
2+
// @allowJs: true
3+
// @checkJs: true
4+
// @outDir: ./out
5+
// @filename: typeFromPrivatePropertyAssignmentJs.js
6+
7+
// @filename: a.js
8+
class C {
9+
/** @type {{ foo?: string } | undefined } */
10+
#a;
11+
/** @type {{ foo?: string } | undefined } */
12+
#b;
13+
m() {
14+
const a = this.#a || {};
15+
this.#b = this.#b || {};
16+
}
17+
}

0 commit comments

Comments
 (0)