diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7f686076f1824..d620376f3602b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -8322,10 +8322,6 @@ "category": "Error", "code": 18029 }, - "An optional chain cannot contain private identifiers.": { - "category": "Error", - "code": 18030 - }, "The intersection '{0}' was reduced to 'never' because property '{1}' has conflicting types in some constituents.": { "category": "Error", "code": 18031 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 59ad1f030220f..71fc00c185cea 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -159,7 +159,6 @@ import { isMetaProperty, isModifierKind, isNonNullExpression, - isPrivateIdentifier, isSetAccessorDeclaration, isStringOrNumericLiteralLike, isTaggedTemplateExpression, @@ -6405,9 +6404,6 @@ namespace Parser { const propertyAccess = isOptionalChain ? factoryCreatePropertyAccessChain(expression, questionDotToken, name) : factoryCreatePropertyAccessExpression(expression, name); - if (isOptionalChain && isPrivateIdentifier(propertyAccess.name)) { - parseErrorAtRange(propertyAccess.name, Diagnostics.An_optional_chain_cannot_contain_private_identifiers); - } if (isExpressionWithTypeArguments(expression) && expression.typeArguments) { const pos = expression.typeArguments.pos - 1; const end = skipTrivia(sourceText, expression.typeArguments.end) + 1; diff --git a/tests/baselines/reference/privateIdentifierChain.1(target=es2015).errors.txt b/tests/baselines/reference/privateIdentifierChain.1(target=es2015).errors.txt new file mode 100644 index 0000000000000..add1c398df613 --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1(target=es2015).errors.txt @@ -0,0 +1,40 @@ +privateIdentifierChain.1.ts(23,17): error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. +privateIdentifierChain.1.ts(24,17): error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. +privateIdentifierChain.1.ts(25,22): error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. + + +==== privateIdentifierChain.1.ts (3 errors) ==== + class A { + a?: A + #b?: A; + getA(): A { + return new A(); + } + constructor() { + this.a = this; + // None of these should error + this?.#b; + this?.a.#b; + this?.getA().#b; + } + } + + class B { + a?: A + getA(): A { + return new A(); + } + constructor() { + this.a = new A(); + this.a?.#b; // Error + ~~ +!!! error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. + this?.a.#b; // Error + ~~ +!!! error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. + this?.getA().#b; // Error + ~~ +!!! error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateIdentifierChain.1(target=es2015).js b/tests/baselines/reference/privateIdentifierChain.1(target=es2015).js new file mode 100644 index 0000000000000..0ba5218faf91c --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1(target=es2015).js @@ -0,0 +1,66 @@ +//// [tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts] //// + +//// [privateIdentifierChain.1.ts] +class A { + a?: A + #b?: A; + getA(): A { + return new A(); + } + constructor() { + this.a = this; + // None of these should error + this?.#b; + this?.a.#b; + this?.getA().#b; + } +} + +class B { + a?: A + getA(): A { + return new A(); + } + constructor() { + this.a = new A(); + this.a?.#b; // Error + this?.a.#b; // Error + this?.getA().#b; // Error + } +} + + +//// [privateIdentifierChain.1.js] +"use strict"; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _A_b; +class A { + getA() { + return new A(); + } + constructor() { + _A_b.set(this, void 0); + this.a = this; + // None of these should error + __classPrivateFieldGet(this, _A_b, "f"); + __classPrivateFieldGet(this === null || this === void 0 ? void 0 : this.a, _A_b, "f"); + __classPrivateFieldGet(this === null || this === void 0 ? void 0 : this.getA(), _A_b, "f"); + } +} +_A_b = new WeakMap(); +class B { + getA() { + return new A(); + } + constructor() { + var _a; + this.a = new A(); + (_a = this.a) === null || _a === void 0 ? void 0 : _a.; // Error + this === null || this === void 0 ? void 0 : this.a.; // Error + this === null || this === void 0 ? void 0 : this.getA().; // Error + } +} diff --git a/tests/baselines/reference/privateIdentifierChain.1(target=es2015).symbols b/tests/baselines/reference/privateIdentifierChain.1(target=es2015).symbols new file mode 100644 index 0000000000000..1225ad245a35d --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1(target=es2015).symbols @@ -0,0 +1,85 @@ +//// [tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts] //// + +=== privateIdentifierChain.1.ts === +class A { +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + a?: A +>a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + #b?: A; +>#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + getA(): A { +>getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + return new A(); +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + } + constructor() { + this.a = this; +>this.a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) +>a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + // None of these should error + this?.#b; +>this?.#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + this?.a.#b; +>this?.a.#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) +>this?.a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) +>a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) + + this?.getA().#b; +>this?.getA().#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) +>this?.getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) +>getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) + } +} + +class B { +>B : Symbol(B, Decl(privateIdentifierChain.1.ts, 13, 1)) + + a?: A +>a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + getA(): A { +>getA : Symbol(B.getA, Decl(privateIdentifierChain.1.ts, 16, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + return new A(); +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + } + constructor() { + this.a = new A(); +>this.a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) +>this : Symbol(B, Decl(privateIdentifierChain.1.ts, 13, 1)) +>a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + this.a?.#b; // Error +>this.a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) +>this : Symbol(B, Decl(privateIdentifierChain.1.ts, 13, 1)) +>a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) + + this?.a.#b; // Error +>this?.a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) +>this : Symbol(B, Decl(privateIdentifierChain.1.ts, 13, 1)) +>a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) + + this?.getA().#b; // Error +>this?.getA : Symbol(B.getA, Decl(privateIdentifierChain.1.ts, 16, 9)) +>this : Symbol(B, Decl(privateIdentifierChain.1.ts, 13, 1)) +>getA : Symbol(B.getA, Decl(privateIdentifierChain.1.ts, 16, 9)) + } +} + diff --git a/tests/baselines/reference/privateIdentifierChain.1(target=es2015).types b/tests/baselines/reference/privateIdentifierChain.1(target=es2015).types new file mode 100644 index 0000000000000..19feefed73ce3 --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1(target=es2015).types @@ -0,0 +1,136 @@ +//// [tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts] //// + +=== privateIdentifierChain.1.ts === +class A { +>A : A +> : ^ + + a?: A +>a : A | undefined +> : ^^^^^^^^^^^^^ + + #b?: A; +>#b : A | undefined +> : ^^^^^^^^^^^^^ + + getA(): A { +>getA : () => A +> : ^^^^^^ + + return new A(); +>new A() : A +> : ^ +>A : typeof A +> : ^^^^^^^^ + } + constructor() { + this.a = this; +>this.a = this : this +> : ^^^^ +>this.a : A | undefined +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ +>a : A | undefined +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ + + // None of these should error + this?.#b; +>this?.#b : A | undefined +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ + + this?.a.#b; +>this?.a.#b : A | undefined +> : ^^^^^^^^^^^^^ +>this?.a : A +> : ^ +>this : this +> : ^^^^ +>a : A +> : ^ + + this?.getA().#b; +>this?.getA().#b : A | undefined +> : ^^^^^^^^^^^^^ +>this?.getA() : A +> : ^ +>this?.getA : () => A +> : ^^^^^^ +>this : this +> : ^^^^ +>getA : () => A +> : ^^^^^^ + } +} + +class B { +>B : B +> : ^ + + a?: A +>a : A | undefined +> : ^^^^^^^^^^^^^ + + getA(): A { +>getA : () => A +> : ^^^^^^ + + return new A(); +>new A() : A +> : ^ +>A : typeof A +> : ^^^^^^^^ + } + constructor() { + this.a = new A(); +>this.a = new A() : A +> : ^ +>this.a : A | undefined +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ +>a : A | undefined +> : ^^^^^^^^^^^^^ +>new A() : A +> : ^ +>A : typeof A +> : ^^^^^^^^ + + this.a?.#b; // Error +>this.a?.#b : any +> : ^^^ +>this.a : A +> : ^ +>this : this +> : ^^^^ +>a : A +> : ^ + + this?.a.#b; // Error +>this?.a.#b : any +> : ^^^ +>this?.a : A +> : ^ +>this : this +> : ^^^^ +>a : A +> : ^ + + this?.getA().#b; // Error +>this?.getA().#b : any +> : ^^^ +>this?.getA() : A +> : ^ +>this?.getA : () => A +> : ^^^^^^ +>this : this +> : ^^^^ +>getA : () => A +> : ^^^^^^ + } +} + diff --git a/tests/baselines/reference/privateIdentifierChain.1(target=esnext).errors.txt b/tests/baselines/reference/privateIdentifierChain.1(target=esnext).errors.txt new file mode 100644 index 0000000000000..add1c398df613 --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1(target=esnext).errors.txt @@ -0,0 +1,40 @@ +privateIdentifierChain.1.ts(23,17): error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. +privateIdentifierChain.1.ts(24,17): error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. +privateIdentifierChain.1.ts(25,22): error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. + + +==== privateIdentifierChain.1.ts (3 errors) ==== + class A { + a?: A + #b?: A; + getA(): A { + return new A(); + } + constructor() { + this.a = this; + // None of these should error + this?.#b; + this?.a.#b; + this?.getA().#b; + } + } + + class B { + a?: A + getA(): A { + return new A(); + } + constructor() { + this.a = new A(); + this.a?.#b; // Error + ~~ +!!! error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. + this?.a.#b; // Error + ~~ +!!! error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. + this?.getA().#b; // Error + ~~ +!!! error TS18013: Property '#b' is not accessible outside class 'A' because it has a private identifier. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privateIdentifierChain.1(target=esnext).js b/tests/baselines/reference/privateIdentifierChain.1(target=esnext).js new file mode 100644 index 0000000000000..8a4b2049a6c75 --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1(target=esnext).js @@ -0,0 +1,58 @@ +//// [tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts] //// + +//// [privateIdentifierChain.1.ts] +class A { + a?: A + #b?: A; + getA(): A { + return new A(); + } + constructor() { + this.a = this; + // None of these should error + this?.#b; + this?.a.#b; + this?.getA().#b; + } +} + +class B { + a?: A + getA(): A { + return new A(); + } + constructor() { + this.a = new A(); + this.a?.#b; // Error + this?.a.#b; // Error + this?.getA().#b; // Error + } +} + + +//// [privateIdentifierChain.1.js] +"use strict"; +class A { + #b; + getA() { + return new A(); + } + constructor() { + this.a = this; + // None of these should error + this?.#b; + this?.a.#b; + this?.getA().#b; + } +} +class B { + getA() { + return new A(); + } + constructor() { + this.a = new A(); + this.a?.#b; // Error + this?.a.#b; // Error + this?.getA().#b; // Error + } +} diff --git a/tests/baselines/reference/privateIdentifierChain.1(target=esnext).symbols b/tests/baselines/reference/privateIdentifierChain.1(target=esnext).symbols new file mode 100644 index 0000000000000..1225ad245a35d --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1(target=esnext).symbols @@ -0,0 +1,85 @@ +//// [tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts] //// + +=== privateIdentifierChain.1.ts === +class A { +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + a?: A +>a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + #b?: A; +>#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + getA(): A { +>getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + return new A(); +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + } + constructor() { + this.a = this; +>this.a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) +>a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + // None of these should error + this?.#b; +>this?.#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + this?.a.#b; +>this?.a.#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) +>this?.a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) +>a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) + + this?.getA().#b; +>this?.getA().#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) +>this?.getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) +>getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) + } +} + +class B { +>B : Symbol(B, Decl(privateIdentifierChain.1.ts, 13, 1)) + + a?: A +>a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + getA(): A { +>getA : Symbol(B.getA, Decl(privateIdentifierChain.1.ts, 16, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + return new A(); +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + } + constructor() { + this.a = new A(); +>this.a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) +>this : Symbol(B, Decl(privateIdentifierChain.1.ts, 13, 1)) +>a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) +>A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + this.a?.#b; // Error +>this.a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) +>this : Symbol(B, Decl(privateIdentifierChain.1.ts, 13, 1)) +>a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) + + this?.a.#b; // Error +>this?.a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) +>this : Symbol(B, Decl(privateIdentifierChain.1.ts, 13, 1)) +>a : Symbol(B.a, Decl(privateIdentifierChain.1.ts, 15, 9)) + + this?.getA().#b; // Error +>this?.getA : Symbol(B.getA, Decl(privateIdentifierChain.1.ts, 16, 9)) +>this : Symbol(B, Decl(privateIdentifierChain.1.ts, 13, 1)) +>getA : Symbol(B.getA, Decl(privateIdentifierChain.1.ts, 16, 9)) + } +} + diff --git a/tests/baselines/reference/privateIdentifierChain.1(target=esnext).types b/tests/baselines/reference/privateIdentifierChain.1(target=esnext).types new file mode 100644 index 0000000000000..19feefed73ce3 --- /dev/null +++ b/tests/baselines/reference/privateIdentifierChain.1(target=esnext).types @@ -0,0 +1,136 @@ +//// [tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts] //// + +=== privateIdentifierChain.1.ts === +class A { +>A : A +> : ^ + + a?: A +>a : A | undefined +> : ^^^^^^^^^^^^^ + + #b?: A; +>#b : A | undefined +> : ^^^^^^^^^^^^^ + + getA(): A { +>getA : () => A +> : ^^^^^^ + + return new A(); +>new A() : A +> : ^ +>A : typeof A +> : ^^^^^^^^ + } + constructor() { + this.a = this; +>this.a = this : this +> : ^^^^ +>this.a : A | undefined +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ +>a : A | undefined +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ + + // None of these should error + this?.#b; +>this?.#b : A | undefined +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ + + this?.a.#b; +>this?.a.#b : A | undefined +> : ^^^^^^^^^^^^^ +>this?.a : A +> : ^ +>this : this +> : ^^^^ +>a : A +> : ^ + + this?.getA().#b; +>this?.getA().#b : A | undefined +> : ^^^^^^^^^^^^^ +>this?.getA() : A +> : ^ +>this?.getA : () => A +> : ^^^^^^ +>this : this +> : ^^^^ +>getA : () => A +> : ^^^^^^ + } +} + +class B { +>B : B +> : ^ + + a?: A +>a : A | undefined +> : ^^^^^^^^^^^^^ + + getA(): A { +>getA : () => A +> : ^^^^^^ + + return new A(); +>new A() : A +> : ^ +>A : typeof A +> : ^^^^^^^^ + } + constructor() { + this.a = new A(); +>this.a = new A() : A +> : ^ +>this.a : A | undefined +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ +>a : A | undefined +> : ^^^^^^^^^^^^^ +>new A() : A +> : ^ +>A : typeof A +> : ^^^^^^^^ + + this.a?.#b; // Error +>this.a?.#b : any +> : ^^^ +>this.a : A +> : ^ +>this : this +> : ^^^^ +>a : A +> : ^ + + this?.a.#b; // Error +>this?.a.#b : any +> : ^^^ +>this?.a : A +> : ^ +>this : this +> : ^^^^ +>a : A +> : ^ + + this?.getA().#b; // Error +>this?.getA().#b : any +> : ^^^ +>this?.getA() : A +> : ^ +>this?.getA : () => A +> : ^^^^^^ +>this : this +> : ^^^^ +>getA : () => A +> : ^^^^^^ + } +} + diff --git a/tests/baselines/reference/privateIdentifierChain.1.errors.txt b/tests/baselines/reference/privateIdentifierChain.1.errors.txt deleted file mode 100644 index f39beb93eda6c..0000000000000 --- a/tests/baselines/reference/privateIdentifierChain.1.errors.txt +++ /dev/null @@ -1,28 +0,0 @@ -privateIdentifierChain.1.ts(8,15): error TS18030: An optional chain cannot contain private identifiers. -privateIdentifierChain.1.ts(9,9): error TS2532: Object is possibly 'undefined'. -privateIdentifierChain.1.ts(9,17): error TS18030: An optional chain cannot contain private identifiers. -privateIdentifierChain.1.ts(10,22): error TS18030: An optional chain cannot contain private identifiers. - - -==== privateIdentifierChain.1.ts (4 errors) ==== - class A { - a?: A - #b?: A; - getA(): A { - return new A(); - } - constructor() { - this?.#b; // Error - ~~ -!!! error TS18030: An optional chain cannot contain private identifiers. - this?.a.#b; // Error - ~~~~~~~ -!!! error TS2532: Object is possibly 'undefined'. - ~~ -!!! error TS18030: An optional chain cannot contain private identifiers. - this?.getA().#b; // Error - ~~ -!!! error TS18030: An optional chain cannot contain private identifiers. - } - } - \ No newline at end of file diff --git a/tests/baselines/reference/privateIdentifierChain.1.js b/tests/baselines/reference/privateIdentifierChain.1.js deleted file mode 100644 index 37e85cb1096c7..0000000000000 --- a/tests/baselines/reference/privateIdentifierChain.1.js +++ /dev/null @@ -1,30 +0,0 @@ -//// [tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts] //// - -//// [privateIdentifierChain.1.ts] -class A { - a?: A - #b?: A; - getA(): A { - return new A(); - } - constructor() { - this?.#b; // Error - this?.a.#b; // Error - this?.getA().#b; // Error - } -} - - -//// [privateIdentifierChain.1.js] -"use strict"; -class A { - #b; - getA() { - return new A(); - } - constructor() { - this?.#b; // Error - this?.a.#b; // Error - this?.getA().#b; // Error - } -} diff --git a/tests/baselines/reference/privateIdentifierChain.1.symbols b/tests/baselines/reference/privateIdentifierChain.1.symbols deleted file mode 100644 index 018ca51f62f21..0000000000000 --- a/tests/baselines/reference/privateIdentifierChain.1.symbols +++ /dev/null @@ -1,40 +0,0 @@ -//// [tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts] //// - -=== privateIdentifierChain.1.ts === -class A { ->A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) - - a?: A ->a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) ->A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) - - #b?: A; ->#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) ->A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) - - getA(): A { ->getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) ->A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) - - return new A(); ->A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) - } - constructor() { - this?.#b; // Error ->this?.#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) ->this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) - - this?.a.#b; // Error ->this?.a.#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) ->this?.a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) ->this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) ->a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) - - this?.getA().#b; // Error ->this?.getA().#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) ->this?.getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) ->this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) ->getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) - } -} - diff --git a/tests/baselines/reference/privateIdentifierChain.1.types b/tests/baselines/reference/privateIdentifierChain.1.types deleted file mode 100644 index 70827d3bcbc0c..0000000000000 --- a/tests/baselines/reference/privateIdentifierChain.1.types +++ /dev/null @@ -1,56 +0,0 @@ -//// [tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts] //// - -=== privateIdentifierChain.1.ts === -class A { ->A : A -> : ^ - - a?: A ->a : A | undefined -> : ^^^^^^^^^^^^^ - - #b?: A; ->#b : A | undefined -> : ^^^^^^^^^^^^^ - - getA(): A { ->getA : () => A -> : ^^^^^^ - - return new A(); ->new A() : A -> : ^ ->A : typeof A -> : ^^^^^^^^ - } - constructor() { - this?.#b; // Error ->this?.#b : A | undefined -> : ^^^^^^^^^^^^^ ->this : this -> : ^^^^ - - this?.a.#b; // Error ->this?.a.#b : A | undefined -> : ^^^^^^^^^^^^^ ->this?.a : A | undefined -> : ^^^^^^^^^^^^^ ->this : this -> : ^^^^ ->a : A | undefined -> : ^^^^^^^^^^^^^ - - this?.getA().#b; // Error ->this?.getA().#b : A | undefined -> : ^^^^^^^^^^^^^ ->this?.getA() : A -> : ^ ->this?.getA : () => A -> : ^^^^^^ ->this : this -> : ^^^^ ->getA : () => A -> : ^^^^^^ - } -} - diff --git a/tests/baselines/reference/privateNameUncheckedJsOptionalChain.errors.txt b/tests/baselines/reference/privateNameUncheckedJsOptionalChain.errors.txt deleted file mode 100644 index 13327c6a0151c..0000000000000 --- a/tests/baselines/reference/privateNameUncheckedJsOptionalChain.errors.txt +++ /dev/null @@ -1,17 +0,0 @@ -privateNameUncheckedJsOptionalChain.js(4,15): error TS18030: An optional chain cannot contain private identifiers. -privateNameUncheckedJsOptionalChain.js(5,15): error TS18030: An optional chain cannot contain private identifiers. - - -==== privateNameUncheckedJsOptionalChain.js (2 errors) ==== - class C { - #bar; - constructor () { - this?.#foo; - ~~~~ -!!! error TS18030: An optional chain cannot contain private identifiers. - this?.#bar; - ~~~~ -!!! error TS18030: An optional chain cannot contain private identifiers. - } - } - \ No newline at end of file diff --git a/tests/baselines/reference/privateNameUncheckedJsOptionalChain.types b/tests/baselines/reference/privateNameUncheckedJsOptionalChain.types index cea9ea7054bd5..9dfc318ecca2b 100644 --- a/tests/baselines/reference/privateNameUncheckedJsOptionalChain.types +++ b/tests/baselines/reference/privateNameUncheckedJsOptionalChain.types @@ -7,18 +7,15 @@ class C { #bar; >#bar : any -> : ^^^ constructor () { this?.#foo; ->this?.#foo : any -> : ^^^ +>this?.#foo : error >this : this > : ^^^^ this?.#bar; >this?.#bar : any -> : ^^^ >this : this > : ^^^^ } diff --git a/tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts b/tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts index e98eeba739d5a..ae0dbe33e0368 100644 --- a/tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts +++ b/tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts @@ -1,5 +1,5 @@ // @strict: true -// @target: esnext +// @target: esnext,es2015 // @useDefineForClassFields: false class A { @@ -9,8 +9,23 @@ class A { return new A(); } constructor() { - this?.#b; // Error - this?.a.#b; // Error - this?.getA().#b; // Error + this.a = this; + // None of these should error + this?.#b; + this?.a.#b; + this?.getA().#b; + } +} + +class B { + a?: A + getA(): A { + return new A(); + } + constructor() { + this.a = new A(); + this.a?.#b; // Error + this?.a.#b; // Error + this?.getA().#b; // Error } }