From fc6ba7cccf1c165d7893f98b80f23fcfd3888418 Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger <53019676+kirkwaiblinger@users.noreply.github.com> Date: Mon, 18 Aug 2025 06:44:13 -0600 Subject: [PATCH] Revert "feat(typescript-estree): forbid invalid keys in `EnumMember` (#11232)" This reverts commit d50a6b11c502c4840f9649789672f49b262ff83c. --- .../snapshots/1-TSESTree-AST.shot | 1 + .../snapshots/5-AST-Alignment-AST.shot | 1 + .../fixtures/_error_/bigint-name/fixture.ts | 3 - .../snapshots/1-TSESTree-Error.shot | 9 --- .../bigint-name/snapshots/2-Babel-Error.shot | 10 --- .../snapshots/3-Alignment-Error.shot | 4 - .../_error_/computed-string-name/fixture.ts | 3 - .../snapshots/1-TSESTree-Error.shot | 9 --- .../snapshots/2-Babel-Error.shot | 10 --- .../snapshots/3-Alignment-Error.shot | 4 - .../fixtures/_error_/number-name/fixture.ts | 3 - .../snapshots/1-TSESTree-Error.shot | 9 --- .../number-name/snapshots/2-Babel-Error.shot | 10 --- .../snapshots/3-Alignment-Error.shot | 4 - .../ast-spec/src/element/TSEnumMember/spec.ts | 45 +++++++++-- .../snapshots/1-TSESTree-Error.shot | 8 +- .../snapshots/3-Alignment-Error.shot | 2 +- .../snapshots/1-TSESTree-Error.shot | 8 +- .../snapshots/3-Alignment-Error.shot | 2 +- .../snapshots/1-TSESTree-Error.shot | 8 +- .../snapshots/3-Alignment-Error.shot | 2 +- .../const-enum/snapshots/1-TSESTree-AST.shot | 2 + .../snapshots/5-AST-Alignment-AST.shot | 16 ++-- .../snapshots/1-TSESTree-AST.shot | 2 + .../snapshots/5-AST-Alignment-AST.shot | 2 + .../snapshots/1-TSESTree-AST.shot | 2 + .../snapshots/5-AST-Alignment-AST.shot | 2 + .../snapshots/1-TSESTree-AST.shot | 2 + .../snapshots/5-AST-Alignment-AST.shot | 2 + .../enum/snapshots/1-TSESTree-AST.shot | 2 + .../enum/snapshots/5-AST-Alignment-AST.shot | 2 + .../fixtures-with-differences-errors.shot | 3 + .../src/rules/naming-convention.ts | 10 ++- .../rules/no-unsafe-enum-comparison.test.ts | 81 +++++++++++++++++++ .../rules/prefer-literal-enum-member.test.ts | 14 ++++ .../rules/switch-exhaustiveness-check.test.ts | 40 +++++++++ .../src/referencer/Referencer.ts | 5 +- packages/typescript-estree/src/convert.ts | 51 +++--------- 38 files changed, 231 insertions(+), 162 deletions(-) delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/fixture.ts delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/1-TSESTree-Error.shot delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/2-Babel-Error.shot delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/3-Alignment-Error.shot delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/fixture.ts delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/1-TSESTree-Error.shot delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/2-Babel-Error.shot delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/3-Alignment-Error.shot delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/fixture.ts delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/1-TSESTree-Error.shot delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/2-Babel-Error.shot delete mode 100644 packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/3-Alignment-Error.shot diff --git a/packages/ast-spec/src/declaration/TSEnumDeclaration/fixtures/with-member-one/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/declaration/TSEnumDeclaration/fixtures/with-member-one/snapshots/1-TSESTree-AST.shot index 9a5146151d36..ddd23006e5d0 100644 --- a/packages/ast-spec/src/declaration/TSEnumDeclaration/fixtures/with-member-one/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/declaration/TSEnumDeclaration/fixtures/with-member-one/snapshots/1-TSESTree-AST.shot @@ -8,6 +8,7 @@ Program { members: [ TSEnumMember { type: "TSEnumMember", + computed: false, id: Identifier { type: "Identifier", decorators: [], diff --git a/packages/ast-spec/src/declaration/TSEnumDeclaration/fixtures/with-member-one/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/declaration/TSEnumDeclaration/fixtures/with-member-one/snapshots/5-AST-Alignment-AST.shot index eeec47153937..90fb8dedf846 100644 --- a/packages/ast-spec/src/declaration/TSEnumDeclaration/fixtures/with-member-one/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/declaration/TSEnumDeclaration/fixtures/with-member-one/snapshots/5-AST-Alignment-AST.shot @@ -15,6 +15,7 @@ Snapshot Diff: - members: Array [ - TSEnumMember { - type: 'TSEnumMember', +- computed: false, - id: Identifier { - type: 'Identifier', - decorators: Array [], diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/fixture.ts b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/fixture.ts deleted file mode 100644 index 3fcd08d2bc99..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/fixture.ts +++ /dev/null @@ -1,3 +0,0 @@ -enum Foo { - 1n = 2 -} diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/1-TSESTree-Error.shot b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/1-TSESTree-Error.shot deleted file mode 100644 index 87ba241f5d40..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/1-TSESTree-Error.shot +++ /dev/null @@ -1,9 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`AST Fixtures > element > TSEnumMember > _error_ > bigint-name > TSESTree - Error`] -TSError - 1 | enum Foo { -> 2 | 1n = 2 - | ^^ An enum member cannot have a numeric name. - 3 | } - 4 | diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/2-Babel-Error.shot b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/2-Babel-Error.shot deleted file mode 100644 index b3afe3afc96e..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/2-Babel-Error.shot +++ /dev/null @@ -1,10 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`AST Fixtures > element > TSEnumMember > _error_ > bigint-name > Babel - Error`] -BabelError - 1 | enum Foo { -> 2 | 1n = 2 - | ^ Unexpected token (2:2) - 3 | } - 4 | - diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/3-Alignment-Error.shot b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/3-Alignment-Error.shot deleted file mode 100644 index 083d80544d72..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/bigint-name/snapshots/3-Alignment-Error.shot +++ /dev/null @@ -1,4 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`AST Fixtures > element > TSEnumMember > _error_ > bigint-name > Error Alignment`] -Both errored diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/fixture.ts b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/fixture.ts deleted file mode 100644 index 2e99a8d3766b..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/fixture.ts +++ /dev/null @@ -1,3 +0,0 @@ -enum Foo { - ["A"] = 2 -} diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/1-TSESTree-Error.shot b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/1-TSESTree-Error.shot deleted file mode 100644 index 2079fad90f2e..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/1-TSESTree-Error.shot +++ /dev/null @@ -1,9 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`AST Fixtures > element > TSEnumMember > _error_ > computed-string-name > TSESTree - Error`] -TSError - 1 | enum Foo { -> 2 | ["A"] = 2 - | ^^^^^ Computed property names are not allowed in enums. - 3 | } - 4 | diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/2-Babel-Error.shot b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/2-Babel-Error.shot deleted file mode 100644 index c68571c79318..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/2-Babel-Error.shot +++ /dev/null @@ -1,10 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`AST Fixtures > element > TSEnumMember > _error_ > computed-string-name > Babel - Error`] -BabelError - 1 | enum Foo { -> 2 | ["A"] = 2 - | ^ Unexpected token (2:2) - 3 | } - 4 | - diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/3-Alignment-Error.shot b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/3-Alignment-Error.shot deleted file mode 100644 index 1331cf0d18b9..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/computed-string-name/snapshots/3-Alignment-Error.shot +++ /dev/null @@ -1,4 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`AST Fixtures > element > TSEnumMember > _error_ > computed-string-name > Error Alignment`] -Both errored diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/fixture.ts b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/fixture.ts deleted file mode 100644 index 174773e65995..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/fixture.ts +++ /dev/null @@ -1,3 +0,0 @@ -enum Foo { - 1 = 2 -} diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/1-TSESTree-Error.shot b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/1-TSESTree-Error.shot deleted file mode 100644 index 8dfacb32e5b9..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/1-TSESTree-Error.shot +++ /dev/null @@ -1,9 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`AST Fixtures > element > TSEnumMember > _error_ > number-name > TSESTree - Error`] -TSError - 1 | enum Foo { -> 2 | 1 = 2 - | ^ An enum member cannot have a numeric name. - 3 | } - 4 | diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/2-Babel-Error.shot b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/2-Babel-Error.shot deleted file mode 100644 index 76b2f2b9c62e..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/2-Babel-Error.shot +++ /dev/null @@ -1,10 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`AST Fixtures > element > TSEnumMember > _error_ > number-name > Babel - Error`] -BabelError - 1 | enum Foo { -> 2 | 1 = 2 - | ^ Unexpected token (2:2) - 3 | } - 4 | - diff --git a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/3-Alignment-Error.shot b/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/3-Alignment-Error.shot deleted file mode 100644 index 34e6cebc91e1..000000000000 --- a/packages/ast-spec/src/element/TSEnumMember/fixtures/_error_/number-name/snapshots/3-Alignment-Error.shot +++ /dev/null @@ -1,4 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`AST Fixtures > element > TSEnumMember > _error_ > number-name > Error Alignment`] -Both errored diff --git a/packages/ast-spec/src/element/TSEnumMember/spec.ts b/packages/ast-spec/src/element/TSEnumMember/spec.ts index a4d1b836f951..a80e963ad278 100644 --- a/packages/ast-spec/src/element/TSEnumMember/spec.ts +++ b/packages/ast-spec/src/element/TSEnumMember/spec.ts @@ -1,15 +1,44 @@ import type { AST_NODE_TYPES } from '../../ast-node-types'; import type { BaseNode } from '../../base/BaseNode'; -import type { Identifier } from '../../expression/Identifier/spec'; -import type { StringLiteral } from '../../expression/literal/StringLiteral/spec'; import type { Expression } from '../../unions/Expression'; +import type { + PropertyNameComputed, + PropertyNameNonComputed, +} from '../../unions/PropertyName'; -export interface TSEnumMember extends BaseNode { +interface TSEnumMemberBase extends BaseNode { type: AST_NODE_TYPES.TSEnumMember; - id: Identifier | StringLiteral; - initializer: Expression | undefined; - /** - * @deprecated the enum member is always non-computed. - */ computed: boolean; + id: + | PropertyNameComputed // this should only happen in semantically invalid code (ts error 1164) + | PropertyNameNonComputed; + initializer: Expression | undefined; +} + +/** + * this should only really happen in semantically invalid code (errors 1164 and 2452) + * + * @example + * ```ts + * // VALID: + * enum Foo { ['a'] } + * + * // INVALID: + * const x = 'a'; + * enum Foo { [x] } + * enum Bar { ['a' + 'b'] } + * ``` + */ +export interface TSEnumMemberComputedName extends TSEnumMemberBase { + computed: true; + id: PropertyNameComputed; } + +export interface TSEnumMemberNonComputedName extends TSEnumMemberBase { + computed: false; + id: PropertyNameNonComputed; +} + +export type TSEnumMember = + | TSEnumMemberComputedName + | TSEnumMemberNonComputedName; diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-number/snapshots/1-TSESTree-Error.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-number/snapshots/1-TSESTree-Error.shot index dc8d857908c8..c64aaae4a4d8 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-number/snapshots/1-TSESTree-Error.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-number/snapshots/1-TSESTree-Error.shot @@ -1,10 +1,4 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`AST Fixtures > legacy-fixtures > basics > _error_ > export-named-enum-computed-number > TSESTree - Error`] -TSError - 2 | - 3 | export enum Foo { -> 4 | [1], - | ^^^ Computed property names are not allowed in enums. - 5 | } - 6 | +NO ERROR diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-number/snapshots/3-Alignment-Error.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-number/snapshots/3-Alignment-Error.shot index f9ae118971e1..f5e14d5d4b27 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-number/snapshots/3-Alignment-Error.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-number/snapshots/3-Alignment-Error.shot @@ -1,4 +1,4 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`AST Fixtures > legacy-fixtures > basics > _error_ > export-named-enum-computed-number > Error Alignment`] -Both errored +Babel errored but TSESTree didn't diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-string/snapshots/1-TSESTree-Error.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-string/snapshots/1-TSESTree-Error.shot index 90ef25fd26d8..866743a38587 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-string/snapshots/1-TSESTree-Error.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-string/snapshots/1-TSESTree-Error.shot @@ -1,10 +1,4 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`AST Fixtures > legacy-fixtures > basics > _error_ > export-named-enum-computed-string > TSESTree - Error`] -TSError - 2 | - 3 | export enum Foo { -> 4 | ['baz'], - | ^^^^^^^ Computed property names are not allowed in enums. - 5 | } - 6 | +NO ERROR diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-string/snapshots/3-Alignment-Error.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-string/snapshots/3-Alignment-Error.shot index 2dc13fd3d5d2..f58190aa21f3 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-string/snapshots/3-Alignment-Error.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-string/snapshots/3-Alignment-Error.shot @@ -1,4 +1,4 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`AST Fixtures > legacy-fixtures > basics > _error_ > export-named-enum-computed-string > Error Alignment`] -Both errored +Babel errored but TSESTree didn't diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-var-ref/snapshots/1-TSESTree-Error.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-var-ref/snapshots/1-TSESTree-Error.shot index 7e31fde5e0c7..85b95f8e17d3 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-var-ref/snapshots/1-TSESTree-Error.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-var-ref/snapshots/1-TSESTree-Error.shot @@ -1,10 +1,4 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`AST Fixtures > legacy-fixtures > basics > _error_ > export-named-enum-computed-var-ref > TSESTree - Error`] -TSError - 2 | - 3 | export enum Foo { -> 4 | [x], - | ^^^ Computed property names are not allowed in enums. - 5 | } - 6 | +NO ERROR diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-var-ref/snapshots/3-Alignment-Error.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-var-ref/snapshots/3-Alignment-Error.shot index 3909357acf22..006e3518ee1f 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-var-ref/snapshots/3-Alignment-Error.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-var-ref/snapshots/3-Alignment-Error.shot @@ -1,4 +1,4 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`AST Fixtures > legacy-fixtures > basics > _error_ > export-named-enum-computed-var-ref > Error Alignment`] -Both errored +Babel errored but TSESTree didn't diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/const-enum/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/const-enum/snapshots/1-TSESTree-AST.shot index 238113e5cc58..9187f52aade3 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/const-enum/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/const-enum/snapshots/1-TSESTree-AST.shot @@ -8,6 +8,7 @@ Program { members: [ TSEnumMember { type: "TSEnumMember", + computed: false, id: Identifier { type: "Identifier", decorators: [], @@ -40,6 +41,7 @@ Program { }, TSEnumMember { type: "TSEnumMember", + computed: false, id: Identifier { type: "Identifier", decorators: [], diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/const-enum/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/const-enum/snapshots/5-AST-Alignment-AST.shot index 20c84325ce31..1c5c321a9cf2 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/const-enum/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/const-enum/snapshots/5-AST-Alignment-AST.shot @@ -15,6 +15,7 @@ Snapshot Diff: - members: Array [ - TSEnumMember { - type: 'TSEnumMember', +- computed: false, - id: Identifier { - type: 'Identifier', - decorators: Array [], @@ -80,6 +81,7 @@ Snapshot Diff: }, - TSEnumMember { - type: 'TSEnumMember', +- computed: false, - id: Identifier { - type: 'Identifier', - decorators: Array [], @@ -119,7 +121,12 @@ Snapshot Diff: - loc: { - start: { column: 15, line: 3 }, - end: { column: 1, line: 6 }, -- }, ++ range: [103, 106], ++ loc: { ++ start: { column: 2, line: 5 }, ++ end: { column: 5, line: 5 }, ++ }, + }, - }, - const: true, - declare: false, @@ -133,12 +140,7 @@ Snapshot Diff: - loc: { - start: { column: 11, line: 3 }, - end: { column: 14, line: 3 }, -+ range: [103, 106], -+ loc: { -+ start: { column: 2, line: 5 }, -+ end: { column: 5, line: 5 }, -+ }, - }, +- }, - }, + ], diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-const-named-enum/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-const-named-enum/snapshots/1-TSESTree-AST.shot index 01c4d100b383..0a35e9756f00 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-const-named-enum/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-const-named-enum/snapshots/1-TSESTree-AST.shot @@ -11,6 +11,7 @@ Program { members: [ TSEnumMember { type: "TSEnumMember", + computed: false, id: Identifier { type: "Identifier", decorators: [], @@ -43,6 +44,7 @@ Program { }, TSEnumMember { type: "TSEnumMember", + computed: false, id: Identifier { type: "Identifier", decorators: [], diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-const-named-enum/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-const-named-enum/snapshots/5-AST-Alignment-AST.shot index 603938fb4270..bc225b94ed0d 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-const-named-enum/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-const-named-enum/snapshots/5-AST-Alignment-AST.shot @@ -19,6 +19,7 @@ Snapshot Diff: - members: Array [ - TSEnumMember { - type: 'TSEnumMember', +- computed: false, - id: Identifier { - type: 'Identifier', - decorators: Array [], @@ -84,6 +85,7 @@ Snapshot Diff: }, - TSEnumMember { - type: 'TSEnumMember', +- computed: false, - id: Identifier { - type: 'Identifier', - decorators: Array [], diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-named-enum/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-named-enum/snapshots/1-TSESTree-AST.shot index f946f794f043..15279e8049d7 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-named-enum/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-named-enum/snapshots/1-TSESTree-AST.shot @@ -11,6 +11,7 @@ Program { members: [ TSEnumMember { type: "TSEnumMember", + computed: false, id: Identifier { type: "Identifier", decorators: [], @@ -43,6 +44,7 @@ Program { }, TSEnumMember { type: "TSEnumMember", + computed: false, id: Identifier { type: "Identifier", decorators: [], diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-named-enum/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-named-enum/snapshots/5-AST-Alignment-AST.shot index eff7ba3226bd..695e866e0f98 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-named-enum/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-declare-named-enum/snapshots/5-AST-Alignment-AST.shot @@ -19,6 +19,7 @@ Snapshot Diff: - members: Array [ - TSEnumMember { - type: 'TSEnumMember', +- computed: false, - id: Identifier { - type: 'Identifier', - decorators: Array [], @@ -84,6 +85,7 @@ Snapshot Diff: }, - TSEnumMember { - type: 'TSEnumMember', +- computed: false, - id: Identifier { - type: 'Identifier', - decorators: Array [], diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-named-enum/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-named-enum/snapshots/1-TSESTree-AST.shot index 8f42d8de69bf..b1554a6d0194 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-named-enum/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-named-enum/snapshots/1-TSESTree-AST.shot @@ -11,6 +11,7 @@ Program { members: [ TSEnumMember { type: "TSEnumMember", + computed: false, id: Identifier { type: "Identifier", decorators: [], @@ -43,6 +44,7 @@ Program { }, TSEnumMember { type: "TSEnumMember", + computed: false, id: Identifier { type: "Identifier", decorators: [], diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-named-enum/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-named-enum/snapshots/5-AST-Alignment-AST.shot index 10c5f8d572d1..b52051becdfb 100644 --- a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-named-enum/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-named-enum/snapshots/5-AST-Alignment-AST.shot @@ -19,6 +19,7 @@ Snapshot Diff: - members: Array [ - TSEnumMember { - type: 'TSEnumMember', +- computed: false, - id: Identifier { - type: 'Identifier', - decorators: Array [], @@ -84,6 +85,7 @@ Snapshot Diff: }, - TSEnumMember { - type: 'TSEnumMember', +- computed: false, - id: Identifier { - type: 'Identifier', - decorators: Array [], diff --git a/packages/ast-spec/src/legacy-fixtures/declare/fixtures/enum/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/legacy-fixtures/declare/fixtures/enum/snapshots/1-TSESTree-AST.shot index e483a20f2a29..513eb9bcd84c 100644 --- a/packages/ast-spec/src/legacy-fixtures/declare/fixtures/enum/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/declare/fixtures/enum/snapshots/1-TSESTree-AST.shot @@ -8,6 +8,7 @@ Program { members: [ TSEnumMember { type: "TSEnumMember", + computed: false, id: Identifier { type: "Identifier", decorators: [], @@ -29,6 +30,7 @@ Program { }, TSEnumMember { type: "TSEnumMember", + computed: false, id: Identifier { type: "Identifier", decorators: [], diff --git a/packages/ast-spec/src/legacy-fixtures/declare/fixtures/enum/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/legacy-fixtures/declare/fixtures/enum/snapshots/5-AST-Alignment-AST.shot index 544b72e407c8..3c1cbd1bc2a0 100644 --- a/packages/ast-spec/src/legacy-fixtures/declare/fixtures/enum/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/legacy-fixtures/declare/fixtures/enum/snapshots/5-AST-Alignment-AST.shot @@ -15,6 +15,7 @@ Snapshot Diff: - members: Array [ - TSEnumMember { - type: 'TSEnumMember', +- computed: false, - id: Identifier { - type: 'Identifier', - decorators: Array [], @@ -58,6 +59,7 @@ Snapshot Diff: }, - TSEnumMember { - type: 'TSEnumMember', +- computed: false, - id: Identifier { - type: 'Identifier', - decorators: Array [], diff --git a/packages/ast-spec/tests/fixtures-with-differences-errors.shot b/packages/ast-spec/tests/fixtures-with-differences-errors.shot index 9bbb4c97243b..006a68578577 100644 --- a/packages/ast-spec/tests/fixtures-with-differences-errors.shot +++ b/packages/ast-spec/tests/fixtures-with-differences-errors.shot @@ -27,6 +27,9 @@ exports[`AST Fixtures > List fixtures with Error differences`] "legacy-fixtures/basics/fixtures/_error_/class-with-constructor-and-type-parameters/fixture.ts", "legacy-fixtures/basics/fixtures/_error_/class-with-two-methods-computed-constructor/fixture.ts", "legacy-fixtures/basics/fixtures/_error_/const-assertions/fixture.ts", + "legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-number/fixture.ts", + "legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-string/fixture.ts", + "legacy-fixtures/basics/fixtures/_error_/export-named-enum-computed-var-ref/fixture.ts", "legacy-fixtures/basics/fixtures/_error_/export-with-import-assertions/fixture.ts", "legacy-fixtures/basics/fixtures/_error_/import-type-error/fixture.ts", "legacy-fixtures/basics/fixtures/_error_/new-target-in-arrow-function-body/fixture.ts", diff --git a/packages/eslint-plugin/src/rules/naming-convention.ts b/packages/eslint-plugin/src/rules/naming-convention.ts index 02b95a5948fc..03500d825163 100644 --- a/packages/eslint-plugin/src/rules/naming-convention.ts +++ b/packages/eslint-plugin/src/rules/naming-convention.ts @@ -631,10 +631,12 @@ export default createRule({ // #region interface - TSEnumMember: { - handler: (node: TSESTree.TSEnumMember, validator): void => { - // Unknown reason, can't get the correct type - const id = node.id as TSESTree.Identifier | TSESTree.StringLiteral; + 'TSEnumMember[computed != true]': { + handler: ( + node: TSESTree.TSEnumMemberNonComputedName, + validator, + ): void => { + const id = node.id; const modifiers = new Set(); if (requiresQuoting(id, compilerOptions.target)) { diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts index 89e28f163314..b592b7fe513d 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts @@ -1121,6 +1121,87 @@ ruleTester.run('no-unsafe-enum-comparison', rule, { }, ], }, + { + code: ` + enum ComputedKey { + ['test-key' /* with comment */] = 1, + } + declare const computedKey: ComputedKey; + computedKey === 1; + `, + errors: [ + { + messageId: 'mismatchedCondition', + suggestions: [ + { + messageId: 'replaceValueWithEnum', + output: ` + enum ComputedKey { + ['test-key' /* with comment */] = 1, + } + declare const computedKey: ComputedKey; + computedKey === ComputedKey['test-key']; + `, + }, + ], + }, + ], + }, + { + code: ` + enum ComputedKey { + [\`test-key\` /* with comment */] = 1, + } + declare const computedKey: ComputedKey; + computedKey === 1; + `, + errors: [ + { + messageId: 'mismatchedCondition', + suggestions: [ + { + messageId: 'replaceValueWithEnum', + output: ` + enum ComputedKey { + [\`test-key\` /* with comment */] = 1, + } + declare const computedKey: ComputedKey; + computedKey === ComputedKey[\`test-key\`]; + `, + }, + ], + }, + ], + }, + { + code: ` + enum ComputedKey { + [\`test- + key\` /* with comment */] = 1, + } + declare const computedKey: ComputedKey; + computedKey === 1; + `, + errors: [ + { + messageId: 'mismatchedCondition', + suggestions: [ + { + messageId: 'replaceValueWithEnum', + output: ` + enum ComputedKey { + [\`test- + key\` /* with comment */] = 1, + } + declare const computedKey: ComputedKey; + computedKey === ComputedKey[\`test- + key\`]; + `, + }, + ], + }, + ], + }, { code: ` enum Fruit { diff --git a/packages/eslint-plugin/tests/rules/prefer-literal-enum-member.test.ts b/packages/eslint-plugin/tests/rules/prefer-literal-enum-member.test.ts index f655c87e9ce2..ea670139ccb3 100644 --- a/packages/eslint-plugin/tests/rules/prefer-literal-enum-member.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-literal-enum-member.test.ts @@ -54,6 +54,11 @@ enum ValidQuotedKey { ` enum ValidQuotedKeyWithAssignment { 'a' = 1, +} + `, + ` +enum ValidKeyWithComputedSyntaxButNoComputedKey { + ['a'], } `, { @@ -102,6 +107,15 @@ enum Foo { }, { code: ` +enum Foo { + ['A-1'] = 1 << 0, + C = ~Foo['A-1'], +} + `, + options: [{ allowBitwiseExpressions: true }], + }, + { + code: ` enum Foo { A = 1 << 0, B = 1 << 1, diff --git a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts index b18e91e4872a..da5b65c8177f 100644 --- a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts +++ b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts @@ -2281,6 +2281,46 @@ switch (value) { }, ], }, + { + code: ` + enum Enum { + 'a' = 1, + [\`key-with + + new-line\`] = 2, + } + + declare const a: Enum; + + switch (a) { + } + `, + errors: [ + { + messageId: 'switchIsNotExhaustive', + suggestions: [ + { + messageId: 'addMissingCases', + output: ` + enum Enum { + 'a' = 1, + [\`key-with + + new-line\`] = 2, + } + + declare const a: Enum; + + switch (a) { + case Enum.a: { throw new Error('Not implemented yet: Enum.a case') } + case Enum['key-with\\n\\n new-line']: { throw new Error('Not implemented yet: Enum[\\'key-with\\\\n\\\\n new-line\\'] case') } + } + `, + }, + ], + }, + ], + }, { code: noFormat` enum Enum { diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index 562921170751..1f621d8f7823 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -668,7 +668,10 @@ export class Referencer extends Visitor { name, new TSEnumMemberDefinition(name, member), ); - } else if (member.id.type === AST_NODE_TYPES.Identifier) { + } else if ( + !member.computed && + member.id.type === AST_NODE_TYPES.Identifier + ) { this.currentScope().defineIdentifier( member.id, new TSEnumMemberDefinition(member.id, member), diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 150c0ee950ea..dccb674537c6 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -476,7 +476,7 @@ export class Converter { >( node: Properties, deprecatedKey: Key, - preferredKey: string | undefined, + preferredKey: string, value: Value, ): Properties & Record { let warned = false; @@ -487,13 +487,10 @@ export class Converter { ? (): Value => value : (): Value => { if (!warned) { - let message = `The '${deprecatedKey}' property is deprecated on ${node.type} nodes.`; - if (preferredKey) { - message += ` Use ${preferredKey} instead.`; - } - message += - ' See https://typescript-eslint.io/troubleshooting/faqs/general#the-key-property-is-deprecated-on-type-nodes-use-key-instead-warnings.'; - process.emitWarning(message, 'DeprecationWarning'); + process.emitWarning( + `The '${deprecatedKey}' property is deprecated on ${node.type} nodes. Use ${preferredKey} instead. See https://typescript-eslint.io/troubleshooting/faqs/general#the-key-property-is-deprecated-on-type-nodes-use-key-instead-warnings.`, + 'DeprecationWarning', + ); warned = true; } @@ -3266,38 +3263,12 @@ export class Converter { } case SyntaxKind.EnumMember: { - const computed = node.name.kind === ts.SyntaxKind.ComputedPropertyName; - if (computed) { - this.#throwUnlessAllowInvalidAST( - node.name, - 'Computed property names are not allowed in enums.', - ); - } - - if ( - node.name.kind === SyntaxKind.NumericLiteral || - node.name.kind === SyntaxKind.BigIntLiteral - ) { - this.#throwUnlessAllowInvalidAST( - node.name, - 'An enum member cannot have a numeric name.', - ); - } - - return this.createNode( - node, - this.#withDeprecatedGetter( - { - type: AST_NODE_TYPES.TSEnumMember, - id: this.convertChild(node.name), - initializer: - node.initializer && this.convertChild(node.initializer), - }, - 'computed', - undefined, - computed, - ), - ); + return this.createNode(node, { + type: AST_NODE_TYPES.TSEnumMember, + computed: node.name.kind === ts.SyntaxKind.ComputedPropertyName, + id: this.convertChild(node.name), + initializer: node.initializer && this.convertChild(node.initializer), + }); } case SyntaxKind.ModuleDeclaration: {