diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5cefd7aa08717..75cc5771b303f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33767,15 +33767,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return grammarErrorOnNode(privId, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); } - if (!isForInStatement(privId.parent)) { - if (!isExpressionNode(privId)) { - return grammarErrorOnNode(privId, Diagnostics.Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression); - } + /** This scenario has checked by {@link checkForInStatement}, so no need to add diagnosis message, original impl see #47116 */ + if (isForInStatement(privId.parent) && privId.parent.initializer === privId) { + return true; + } - const isInOperation = isBinaryExpression(privId.parent) && privId.parent.operatorToken.kind === SyntaxKind.InKeyword; - if (!getSymbolForPrivateIdentifierExpression(privId) && !isInOperation) { - return grammarErrorOnNode(privId, Diagnostics.Cannot_find_name_0, idText(privId)); - } + if (!isExpressionNode(privId)) { + return grammarErrorOnNode(privId, Diagnostics.Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression); + } + + if (!getSymbolForPrivateIdentifierExpression(privId)) { + return grammarErrorOnNode(privId, Diagnostics.Cannot_find_name_0, idText(privId)); } return false; diff --git a/tests/baselines/reference/privateNameInInExpression(target=es2022).errors.txt b/tests/baselines/reference/privateNameInInExpression(target=es2022).errors.txt index b4e61e41e2ba3..60fbf830c916a 100644 --- a/tests/baselines/reference/privateNameInInExpression(target=es2022).errors.txt +++ b/tests/baselines/reference/privateNameInInExpression(target=es2022).errors.txt @@ -1,13 +1,15 @@ privateNameInInExpression.ts(21,29): error TS2571: Object is of type 'unknown'. +privateNameInInExpression.ts(23,19): error TS2304: Cannot find name '#fiel'. privateNameInInExpression.ts(23,19): error TS2339: Property '#fiel' does not exist on type 'any'. privateNameInInExpression.ts(25,20): error TS1451: Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression privateNameInInExpression.ts(27,14): error TS2406: The left-hand side of a 'for...in' statement must be a variable or a property access. privateNameInInExpression.ts(29,23): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'boolean'. -privateNameInInExpression.ts(43,27): error TS18047: 'u' is possibly 'null'. -privateNameInInExpression.ts(114,12): error TS18016: Private identifiers are not allowed outside class bodies. +privateNameInInExpression.ts(31,23): error TS1451: Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression +privateNameInInExpression.ts(45,27): error TS18047: 'u' is possibly 'null'. +privateNameInInExpression.ts(116,12): error TS18016: Private identifiers are not allowed outside class bodies. -==== privateNameInInExpression.ts (7 errors) ==== +==== privateNameInInExpression.ts (9 errors) ==== class Foo { #field = 1; static #staticField = 2; @@ -34,6 +36,8 @@ privateNameInInExpression.ts(114,12): error TS18016: Private identifiers are not const b = #fiel in v; // Bad - typo in privateID ~~~~~ +!!! error TS2304: Cannot find name '#fiel'. + ~~~~~ !!! error TS2339: Property '#fiel' does not exist on type 'any'. const c = (#field) in v; // Bad - privateID is not an expression on its own @@ -47,6 +51,10 @@ privateNameInInExpression.ts(114,12): error TS18016: Private identifiers are not for (let d in #field in v) { /**/ } // Bad - rhs of in should be a object/any ~~~~~~~~~~~ !!! error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'boolean'. + + for (let d in #field) { /**/ } // Bad - private field not allowed in expression of forInStatement + ~~~~~~ +!!! error TS1451: Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression } whitespace(v: any) { const a = v && /*0*/#field/*1*/ diff --git a/tests/baselines/reference/privateNameInInExpression(target=es2022).js b/tests/baselines/reference/privateNameInInExpression(target=es2022).js index ae7f81a9ea610..3f2227df186d2 100644 --- a/tests/baselines/reference/privateNameInInExpression(target=es2022).js +++ b/tests/baselines/reference/privateNameInInExpression(target=es2022).js @@ -30,6 +30,8 @@ class Foo { for (#field in v) { /**/ } // Bad - 'in' not allowed for (let d in #field in v) { /**/ } // Bad - rhs of in should be a object/any + + for (let d in #field) { /**/ } // Bad - private field not allowed in expression of forInStatement } whitespace(v: any) { const a = v && /*0*/#field/*1*/ @@ -139,6 +141,7 @@ class Foo { const c = (#field) in v; // Bad - privateID is not an expression on its own for (#field in v) { /**/ } // Bad - 'in' not allowed for (let d in #field in v) { /**/ } // Bad - rhs of in should be a object/any + for (let d in #field) { /**/ } // Bad - private field not allowed in expression of forInStatement } whitespace(v) { const a = v && /*0*/ #field /*1*/ diff --git a/tests/baselines/reference/privateNameInInExpression(target=es2022).symbols b/tests/baselines/reference/privateNameInInExpression(target=es2022).symbols index b72d6f47dc659..486a974e6d5ba 100644 --- a/tests/baselines/reference/privateNameInInExpression(target=es2022).symbols +++ b/tests/baselines/reference/privateNameInInExpression(target=es2022).symbols @@ -75,176 +75,179 @@ class Foo { >d : Symbol(d, Decl(privateNameInInExpression.ts, 28, 16)) >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) >v : Symbol(v, Decl(privateNameInInExpression.ts, 19, 11)) + + for (let d in #field) { /**/ } // Bad - private field not allowed in expression of forInStatement +>d : Symbol(d, Decl(privateNameInInExpression.ts, 30, 16)) } whitespace(v: any) { ->whitespace : Symbol(Foo.whitespace, Decl(privateNameInInExpression.ts, 29, 5)) ->v : Symbol(v, Decl(privateNameInInExpression.ts, 30, 15)) +>whitespace : Symbol(Foo.whitespace, Decl(privateNameInInExpression.ts, 31, 5)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 32, 15)) const a = v && /*0*/#field/*1*/ ->a : Symbol(a, Decl(privateNameInInExpression.ts, 31, 13)) ->v : Symbol(v, Decl(privateNameInInExpression.ts, 30, 15)) +>a : Symbol(a, Decl(privateNameInInExpression.ts, 33, 13)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 32, 15)) >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) /*2*/in/*3*/ /*4*/v/*5*/ ->v : Symbol(v, Decl(privateNameInInExpression.ts, 30, 15)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 32, 15)) } flow(u: unknown, n: never, fb: Foo | Bar, fs: FooSub, b: Bar, fsb: FooSub | Bar, fsfb: Foo | FooSub | Bar) { ->flow : Symbol(Foo.flow, Decl(privateNameInInExpression.ts, 34, 5)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) ->n : Symbol(n, Decl(privateNameInInExpression.ts, 35, 20)) ->fb : Symbol(fb, Decl(privateNameInInExpression.ts, 35, 30)) +>flow : Symbol(Foo.flow, Decl(privateNameInInExpression.ts, 36, 5)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) +>n : Symbol(n, Decl(privateNameInInExpression.ts, 37, 20)) +>fb : Symbol(fb, Decl(privateNameInInExpression.ts, 37, 30)) >Foo : Symbol(Foo, Decl(privateNameInInExpression.ts, 0, 0)) ->Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 109, 48)) ->fs : Symbol(fs, Decl(privateNameInInExpression.ts, 35, 45)) ->FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 107, 1)) ->b : Symbol(b, Decl(privateNameInInExpression.ts, 35, 57)) ->Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 109, 48)) ->fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 35, 65)) ->FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 107, 1)) ->Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 109, 48)) ->fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 35, 84)) +>Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 111, 48)) +>fs : Symbol(fs, Decl(privateNameInInExpression.ts, 37, 45)) +>FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 109, 1)) +>b : Symbol(b, Decl(privateNameInInExpression.ts, 37, 57)) +>Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 111, 48)) +>fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 37, 65)) +>FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 109, 1)) +>Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 111, 48)) +>fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 37, 84)) >Foo : Symbol(Foo, Decl(privateNameInInExpression.ts, 0, 0)) ->FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 107, 1)) ->Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 109, 48)) +>FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 109, 1)) +>Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 111, 48)) if (typeof u === 'object') { ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) if (#field in n) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->n : Symbol(n, Decl(privateNameInInExpression.ts, 35, 20)) +>n : Symbol(n, Decl(privateNameInInExpression.ts, 37, 20)) n; // good n is never ->n : Symbol(n, Decl(privateNameInInExpression.ts, 35, 20)) +>n : Symbol(n, Decl(privateNameInInExpression.ts, 37, 20)) } if (#field in u) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) u; // good u is Foo ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } else { u; // good u is object | null ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } if (u !== null) { ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) if (#field in u) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) u; // good u is Foo ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } else { u; // good u is object ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } if (#method in u) { >#method : Symbol(Foo.#method, Decl(privateNameInInExpression.ts, 2, 28)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) u; // good u is Foo ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } if (#staticField in u) { >#staticField : Symbol(Foo.#staticField, Decl(privateNameInInExpression.ts, 1, 15)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) u; // good u is typeof Foo ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } if (#staticMethod in u) { >#staticMethod : Symbol(Foo.#staticMethod, Decl(privateNameInInExpression.ts, 3, 16)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) u; // good u is typeof Foo ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } } } if (#field in fb) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->fb : Symbol(fb, Decl(privateNameInInExpression.ts, 35, 30)) +>fb : Symbol(fb, Decl(privateNameInInExpression.ts, 37, 30)) fb; // good fb is Foo ->fb : Symbol(fb, Decl(privateNameInInExpression.ts, 35, 30)) +>fb : Symbol(fb, Decl(privateNameInInExpression.ts, 37, 30)) } else { fb; // good fb is Bar ->fb : Symbol(fb, Decl(privateNameInInExpression.ts, 35, 30)) +>fb : Symbol(fb, Decl(privateNameInInExpression.ts, 37, 30)) } if (#field in fs) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->fs : Symbol(fs, Decl(privateNameInInExpression.ts, 35, 45)) +>fs : Symbol(fs, Decl(privateNameInInExpression.ts, 37, 45)) fs; // good fs is FooSub ->fs : Symbol(fs, Decl(privateNameInInExpression.ts, 35, 45)) +>fs : Symbol(fs, Decl(privateNameInInExpression.ts, 37, 45)) } else { fs; // good fs is never ->fs : Symbol(fs, Decl(privateNameInInExpression.ts, 35, 45)) +>fs : Symbol(fs, Decl(privateNameInInExpression.ts, 37, 45)) } if (#field in b) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->b : Symbol(b, Decl(privateNameInInExpression.ts, 35, 57)) +>b : Symbol(b, Decl(privateNameInInExpression.ts, 37, 57)) b; // good b is 'Bar & Foo' ->b : Symbol(b, Decl(privateNameInInExpression.ts, 35, 57)) +>b : Symbol(b, Decl(privateNameInInExpression.ts, 37, 57)) } else { b; // good b is Bar ->b : Symbol(b, Decl(privateNameInInExpression.ts, 35, 57)) +>b : Symbol(b, Decl(privateNameInInExpression.ts, 37, 57)) } if (#field in fsb) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 35, 65)) +>fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 37, 65)) fsb; // good fsb is FooSub ->fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 35, 65)) +>fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 37, 65)) } else { fsb; // good fsb is Bar ->fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 35, 65)) +>fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 37, 65)) } if (#field in fsfb) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 35, 84)) +>fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 37, 84)) fsfb; // good fsfb is 'Foo | FooSub' ->fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 35, 84)) +>fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 37, 84)) } else { fsfb; // good fsfb is Bar ->fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 35, 84)) +>fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 37, 84)) } class Nested { ->Nested : Symbol(Nested, Decl(privateNameInInExpression.ts, 97, 9)) +>Nested : Symbol(Nested, Decl(privateNameInInExpression.ts, 99, 9)) m(v: any) { ->m : Symbol(Nested.m, Decl(privateNameInInExpression.ts, 99, 22)) ->v : Symbol(v, Decl(privateNameInInExpression.ts, 100, 14)) +>m : Symbol(Nested.m, Decl(privateNameInInExpression.ts, 101, 22)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 102, 14)) if (#field in v) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->v : Symbol(v, Decl(privateNameInInExpression.ts, 100, 14)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 102, 14)) v; // good v is Foo ->v : Symbol(v, Decl(privateNameInInExpression.ts, 100, 14)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 102, 14)) } } } @@ -252,20 +255,20 @@ class Foo { } class FooSub extends Foo { subTypeOfFoo = true } ->FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 107, 1)) +>FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 109, 1)) >Foo : Symbol(Foo, Decl(privateNameInInExpression.ts, 0, 0)) ->subTypeOfFoo : Symbol(FooSub.subTypeOfFoo, Decl(privateNameInInExpression.ts, 109, 26)) +>subTypeOfFoo : Symbol(FooSub.subTypeOfFoo, Decl(privateNameInInExpression.ts, 111, 26)) class Bar { notFoo = true } ->Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 109, 48)) ->notFoo : Symbol(Bar.notFoo, Decl(privateNameInInExpression.ts, 110, 11)) +>Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 111, 48)) +>notFoo : Symbol(Bar.notFoo, Decl(privateNameInInExpression.ts, 112, 11)) function badSyntax(v: Foo) { ->badSyntax : Symbol(badSyntax, Decl(privateNameInInExpression.ts, 110, 27)) ->v : Symbol(v, Decl(privateNameInInExpression.ts, 112, 19)) +>badSyntax : Symbol(badSyntax, Decl(privateNameInInExpression.ts, 112, 27)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 114, 19)) >Foo : Symbol(Foo, Decl(privateNameInInExpression.ts, 0, 0)) return #field in v; // Bad - outside of class ->v : Symbol(v, Decl(privateNameInInExpression.ts, 112, 19)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 114, 19)) } diff --git a/tests/baselines/reference/privateNameInInExpression(target=es2022).types b/tests/baselines/reference/privateNameInInExpression(target=es2022).types index 99a54a5d427a0..84469eccef5f0 100644 --- a/tests/baselines/reference/privateNameInInExpression(target=es2022).types +++ b/tests/baselines/reference/privateNameInInExpression(target=es2022).types @@ -166,6 +166,10 @@ class Foo { > : ^^^ >v : any > : ^^^ + + for (let d in #field) { /**/ } // Bad - private field not allowed in expression of forInStatement +>d : string +> : ^^^^^^ } whitespace(v: any) { >whitespace : (v: any) => void diff --git a/tests/baselines/reference/privateNameInInExpression(target=esnext).errors.txt b/tests/baselines/reference/privateNameInInExpression(target=esnext).errors.txt index b4e61e41e2ba3..60fbf830c916a 100644 --- a/tests/baselines/reference/privateNameInInExpression(target=esnext).errors.txt +++ b/tests/baselines/reference/privateNameInInExpression(target=esnext).errors.txt @@ -1,13 +1,15 @@ privateNameInInExpression.ts(21,29): error TS2571: Object is of type 'unknown'. +privateNameInInExpression.ts(23,19): error TS2304: Cannot find name '#fiel'. privateNameInInExpression.ts(23,19): error TS2339: Property '#fiel' does not exist on type 'any'. privateNameInInExpression.ts(25,20): error TS1451: Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression privateNameInInExpression.ts(27,14): error TS2406: The left-hand side of a 'for...in' statement must be a variable or a property access. privateNameInInExpression.ts(29,23): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'boolean'. -privateNameInInExpression.ts(43,27): error TS18047: 'u' is possibly 'null'. -privateNameInInExpression.ts(114,12): error TS18016: Private identifiers are not allowed outside class bodies. +privateNameInInExpression.ts(31,23): error TS1451: Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression +privateNameInInExpression.ts(45,27): error TS18047: 'u' is possibly 'null'. +privateNameInInExpression.ts(116,12): error TS18016: Private identifiers are not allowed outside class bodies. -==== privateNameInInExpression.ts (7 errors) ==== +==== privateNameInInExpression.ts (9 errors) ==== class Foo { #field = 1; static #staticField = 2; @@ -34,6 +36,8 @@ privateNameInInExpression.ts(114,12): error TS18016: Private identifiers are not const b = #fiel in v; // Bad - typo in privateID ~~~~~ +!!! error TS2304: Cannot find name '#fiel'. + ~~~~~ !!! error TS2339: Property '#fiel' does not exist on type 'any'. const c = (#field) in v; // Bad - privateID is not an expression on its own @@ -47,6 +51,10 @@ privateNameInInExpression.ts(114,12): error TS18016: Private identifiers are not for (let d in #field in v) { /**/ } // Bad - rhs of in should be a object/any ~~~~~~~~~~~ !!! error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'boolean'. + + for (let d in #field) { /**/ } // Bad - private field not allowed in expression of forInStatement + ~~~~~~ +!!! error TS1451: Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression } whitespace(v: any) { const a = v && /*0*/#field/*1*/ diff --git a/tests/baselines/reference/privateNameInInExpression(target=esnext).js b/tests/baselines/reference/privateNameInInExpression(target=esnext).js index ae7f81a9ea610..3f2227df186d2 100644 --- a/tests/baselines/reference/privateNameInInExpression(target=esnext).js +++ b/tests/baselines/reference/privateNameInInExpression(target=esnext).js @@ -30,6 +30,8 @@ class Foo { for (#field in v) { /**/ } // Bad - 'in' not allowed for (let d in #field in v) { /**/ } // Bad - rhs of in should be a object/any + + for (let d in #field) { /**/ } // Bad - private field not allowed in expression of forInStatement } whitespace(v: any) { const a = v && /*0*/#field/*1*/ @@ -139,6 +141,7 @@ class Foo { const c = (#field) in v; // Bad - privateID is not an expression on its own for (#field in v) { /**/ } // Bad - 'in' not allowed for (let d in #field in v) { /**/ } // Bad - rhs of in should be a object/any + for (let d in #field) { /**/ } // Bad - private field not allowed in expression of forInStatement } whitespace(v) { const a = v && /*0*/ #field /*1*/ diff --git a/tests/baselines/reference/privateNameInInExpression(target=esnext).symbols b/tests/baselines/reference/privateNameInInExpression(target=esnext).symbols index b72d6f47dc659..486a974e6d5ba 100644 --- a/tests/baselines/reference/privateNameInInExpression(target=esnext).symbols +++ b/tests/baselines/reference/privateNameInInExpression(target=esnext).symbols @@ -75,176 +75,179 @@ class Foo { >d : Symbol(d, Decl(privateNameInInExpression.ts, 28, 16)) >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) >v : Symbol(v, Decl(privateNameInInExpression.ts, 19, 11)) + + for (let d in #field) { /**/ } // Bad - private field not allowed in expression of forInStatement +>d : Symbol(d, Decl(privateNameInInExpression.ts, 30, 16)) } whitespace(v: any) { ->whitespace : Symbol(Foo.whitespace, Decl(privateNameInInExpression.ts, 29, 5)) ->v : Symbol(v, Decl(privateNameInInExpression.ts, 30, 15)) +>whitespace : Symbol(Foo.whitespace, Decl(privateNameInInExpression.ts, 31, 5)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 32, 15)) const a = v && /*0*/#field/*1*/ ->a : Symbol(a, Decl(privateNameInInExpression.ts, 31, 13)) ->v : Symbol(v, Decl(privateNameInInExpression.ts, 30, 15)) +>a : Symbol(a, Decl(privateNameInInExpression.ts, 33, 13)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 32, 15)) >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) /*2*/in/*3*/ /*4*/v/*5*/ ->v : Symbol(v, Decl(privateNameInInExpression.ts, 30, 15)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 32, 15)) } flow(u: unknown, n: never, fb: Foo | Bar, fs: FooSub, b: Bar, fsb: FooSub | Bar, fsfb: Foo | FooSub | Bar) { ->flow : Symbol(Foo.flow, Decl(privateNameInInExpression.ts, 34, 5)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) ->n : Symbol(n, Decl(privateNameInInExpression.ts, 35, 20)) ->fb : Symbol(fb, Decl(privateNameInInExpression.ts, 35, 30)) +>flow : Symbol(Foo.flow, Decl(privateNameInInExpression.ts, 36, 5)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) +>n : Symbol(n, Decl(privateNameInInExpression.ts, 37, 20)) +>fb : Symbol(fb, Decl(privateNameInInExpression.ts, 37, 30)) >Foo : Symbol(Foo, Decl(privateNameInInExpression.ts, 0, 0)) ->Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 109, 48)) ->fs : Symbol(fs, Decl(privateNameInInExpression.ts, 35, 45)) ->FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 107, 1)) ->b : Symbol(b, Decl(privateNameInInExpression.ts, 35, 57)) ->Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 109, 48)) ->fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 35, 65)) ->FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 107, 1)) ->Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 109, 48)) ->fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 35, 84)) +>Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 111, 48)) +>fs : Symbol(fs, Decl(privateNameInInExpression.ts, 37, 45)) +>FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 109, 1)) +>b : Symbol(b, Decl(privateNameInInExpression.ts, 37, 57)) +>Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 111, 48)) +>fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 37, 65)) +>FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 109, 1)) +>Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 111, 48)) +>fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 37, 84)) >Foo : Symbol(Foo, Decl(privateNameInInExpression.ts, 0, 0)) ->FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 107, 1)) ->Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 109, 48)) +>FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 109, 1)) +>Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 111, 48)) if (typeof u === 'object') { ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) if (#field in n) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->n : Symbol(n, Decl(privateNameInInExpression.ts, 35, 20)) +>n : Symbol(n, Decl(privateNameInInExpression.ts, 37, 20)) n; // good n is never ->n : Symbol(n, Decl(privateNameInInExpression.ts, 35, 20)) +>n : Symbol(n, Decl(privateNameInInExpression.ts, 37, 20)) } if (#field in u) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) u; // good u is Foo ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } else { u; // good u is object | null ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } if (u !== null) { ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) if (#field in u) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) u; // good u is Foo ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } else { u; // good u is object ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } if (#method in u) { >#method : Symbol(Foo.#method, Decl(privateNameInInExpression.ts, 2, 28)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) u; // good u is Foo ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } if (#staticField in u) { >#staticField : Symbol(Foo.#staticField, Decl(privateNameInInExpression.ts, 1, 15)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) u; // good u is typeof Foo ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } if (#staticMethod in u) { >#staticMethod : Symbol(Foo.#staticMethod, Decl(privateNameInInExpression.ts, 3, 16)) ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) u; // good u is typeof Foo ->u : Symbol(u, Decl(privateNameInInExpression.ts, 35, 9)) +>u : Symbol(u, Decl(privateNameInInExpression.ts, 37, 9)) } } } if (#field in fb) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->fb : Symbol(fb, Decl(privateNameInInExpression.ts, 35, 30)) +>fb : Symbol(fb, Decl(privateNameInInExpression.ts, 37, 30)) fb; // good fb is Foo ->fb : Symbol(fb, Decl(privateNameInInExpression.ts, 35, 30)) +>fb : Symbol(fb, Decl(privateNameInInExpression.ts, 37, 30)) } else { fb; // good fb is Bar ->fb : Symbol(fb, Decl(privateNameInInExpression.ts, 35, 30)) +>fb : Symbol(fb, Decl(privateNameInInExpression.ts, 37, 30)) } if (#field in fs) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->fs : Symbol(fs, Decl(privateNameInInExpression.ts, 35, 45)) +>fs : Symbol(fs, Decl(privateNameInInExpression.ts, 37, 45)) fs; // good fs is FooSub ->fs : Symbol(fs, Decl(privateNameInInExpression.ts, 35, 45)) +>fs : Symbol(fs, Decl(privateNameInInExpression.ts, 37, 45)) } else { fs; // good fs is never ->fs : Symbol(fs, Decl(privateNameInInExpression.ts, 35, 45)) +>fs : Symbol(fs, Decl(privateNameInInExpression.ts, 37, 45)) } if (#field in b) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->b : Symbol(b, Decl(privateNameInInExpression.ts, 35, 57)) +>b : Symbol(b, Decl(privateNameInInExpression.ts, 37, 57)) b; // good b is 'Bar & Foo' ->b : Symbol(b, Decl(privateNameInInExpression.ts, 35, 57)) +>b : Symbol(b, Decl(privateNameInInExpression.ts, 37, 57)) } else { b; // good b is Bar ->b : Symbol(b, Decl(privateNameInInExpression.ts, 35, 57)) +>b : Symbol(b, Decl(privateNameInInExpression.ts, 37, 57)) } if (#field in fsb) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 35, 65)) +>fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 37, 65)) fsb; // good fsb is FooSub ->fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 35, 65)) +>fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 37, 65)) } else { fsb; // good fsb is Bar ->fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 35, 65)) +>fsb : Symbol(fsb, Decl(privateNameInInExpression.ts, 37, 65)) } if (#field in fsfb) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 35, 84)) +>fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 37, 84)) fsfb; // good fsfb is 'Foo | FooSub' ->fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 35, 84)) +>fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 37, 84)) } else { fsfb; // good fsfb is Bar ->fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 35, 84)) +>fsfb : Symbol(fsfb, Decl(privateNameInInExpression.ts, 37, 84)) } class Nested { ->Nested : Symbol(Nested, Decl(privateNameInInExpression.ts, 97, 9)) +>Nested : Symbol(Nested, Decl(privateNameInInExpression.ts, 99, 9)) m(v: any) { ->m : Symbol(Nested.m, Decl(privateNameInInExpression.ts, 99, 22)) ->v : Symbol(v, Decl(privateNameInInExpression.ts, 100, 14)) +>m : Symbol(Nested.m, Decl(privateNameInInExpression.ts, 101, 22)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 102, 14)) if (#field in v) { >#field : Symbol(Foo.#field, Decl(privateNameInInExpression.ts, 0, 11)) ->v : Symbol(v, Decl(privateNameInInExpression.ts, 100, 14)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 102, 14)) v; // good v is Foo ->v : Symbol(v, Decl(privateNameInInExpression.ts, 100, 14)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 102, 14)) } } } @@ -252,20 +255,20 @@ class Foo { } class FooSub extends Foo { subTypeOfFoo = true } ->FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 107, 1)) +>FooSub : Symbol(FooSub, Decl(privateNameInInExpression.ts, 109, 1)) >Foo : Symbol(Foo, Decl(privateNameInInExpression.ts, 0, 0)) ->subTypeOfFoo : Symbol(FooSub.subTypeOfFoo, Decl(privateNameInInExpression.ts, 109, 26)) +>subTypeOfFoo : Symbol(FooSub.subTypeOfFoo, Decl(privateNameInInExpression.ts, 111, 26)) class Bar { notFoo = true } ->Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 109, 48)) ->notFoo : Symbol(Bar.notFoo, Decl(privateNameInInExpression.ts, 110, 11)) +>Bar : Symbol(Bar, Decl(privateNameInInExpression.ts, 111, 48)) +>notFoo : Symbol(Bar.notFoo, Decl(privateNameInInExpression.ts, 112, 11)) function badSyntax(v: Foo) { ->badSyntax : Symbol(badSyntax, Decl(privateNameInInExpression.ts, 110, 27)) ->v : Symbol(v, Decl(privateNameInInExpression.ts, 112, 19)) +>badSyntax : Symbol(badSyntax, Decl(privateNameInInExpression.ts, 112, 27)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 114, 19)) >Foo : Symbol(Foo, Decl(privateNameInInExpression.ts, 0, 0)) return #field in v; // Bad - outside of class ->v : Symbol(v, Decl(privateNameInInExpression.ts, 112, 19)) +>v : Symbol(v, Decl(privateNameInInExpression.ts, 114, 19)) } diff --git a/tests/baselines/reference/privateNameInInExpression(target=esnext).types b/tests/baselines/reference/privateNameInInExpression(target=esnext).types index 99a54a5d427a0..84469eccef5f0 100644 --- a/tests/baselines/reference/privateNameInInExpression(target=esnext).types +++ b/tests/baselines/reference/privateNameInInExpression(target=esnext).types @@ -166,6 +166,10 @@ class Foo { > : ^^^ >v : any > : ^^^ + + for (let d in #field) { /**/ } // Bad - private field not allowed in expression of forInStatement +>d : string +> : ^^^^^^ } whitespace(v: any) { >whitespace : (v: any) => void diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts b/tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts index cc8c876e81f3a..9f878425ee433 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts @@ -31,6 +31,8 @@ class Foo { for (#field in v) { /**/ } // Bad - 'in' not allowed for (let d in #field in v) { /**/ } // Bad - rhs of in should be a object/any + + for (let d in #field) { /**/ } // Bad - private field not allowed in expression of forInStatement } whitespace(v: any) { const a = v && /*0*/#field/*1*/