mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(linter): @typescript-eslint/prefer-literal-enum-member (#3134)
Related issue: https://github.com/oxc-project/oxc/issues/2180 original implementation - code: https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/rules/prefer-literal-enum-member.ts - test: https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/tests/rules/prefer-literal-enum-member.test.ts - doc: https://typescript-eslint.io/rules/prefer-literal-enum-member/
This commit is contained in:
parent
a52e321b25
commit
80cf0b2b2e
3 changed files with 613 additions and 0 deletions
|
|
@ -141,6 +141,7 @@ mod typescript {
|
|||
pub mod prefer_enum_initializers;
|
||||
pub mod prefer_for_of;
|
||||
pub mod prefer_function_type;
|
||||
pub mod prefer_literal_enum_member;
|
||||
pub mod prefer_ts_expect_error;
|
||||
pub mod triple_slash_reference;
|
||||
}
|
||||
|
|
@ -492,6 +493,7 @@ oxc_macros::declare_all_lint_rules! {
|
|||
typescript::prefer_function_type,
|
||||
typescript::prefer_ts_expect_error,
|
||||
typescript::triple_slash_reference,
|
||||
typescript::prefer_literal_enum_member,
|
||||
jest::expect_expect,
|
||||
jest::max_expects,
|
||||
jest::no_alias_methods,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,347 @@
|
|||
use oxc_ast::{ast::Expression, AstKind};
|
||||
use oxc_diagnostics::{
|
||||
miette::{self, Diagnostic},
|
||||
thiserror::Error,
|
||||
};
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
use oxc_span::Span;
|
||||
use oxc_syntax::operator::{BinaryOperator, UnaryOperator};
|
||||
|
||||
use crate::{context::LintContext, rule::Rule, AstNode};
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error("typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).")]
|
||||
#[diagnostic(severity(warning), help("Require all enum members to be literal values."))]
|
||||
struct PreferLiteralEnumMemberDiagnostic(#[label] pub Span);
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct PreferLiteralEnumMember {
|
||||
allow_bitwise_expressions: bool,
|
||||
}
|
||||
|
||||
declare_oxc_lint!(
|
||||
/// ### What it does
|
||||
/// Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// TypeScript allows the value of an enum member to be many different kinds of valid JavaScript expressions.
|
||||
/// However, because enums create their own scope whereby each enum member becomes a variable in that scope, developers are often surprised at the resultant values.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```javascript
|
||||
/// const imOutside = 2;
|
||||
/// const b = 2;
|
||||
/// enum Foo {
|
||||
/// outer = imOutside,
|
||||
/// a = 1,
|
||||
/// b = a,
|
||||
/// c = b,
|
||||
/// }
|
||||
/// ```
|
||||
PreferLiteralEnumMember,
|
||||
correctness
|
||||
);
|
||||
|
||||
impl Rule for PreferLiteralEnumMember {
|
||||
fn from_configuration(value: serde_json::Value) -> Self {
|
||||
let options: Option<&serde_json::Value> = value.get(0);
|
||||
|
||||
Self {
|
||||
allow_bitwise_expressions: options
|
||||
.and_then(|x| x.get("allowBitwiseExpressions"))
|
||||
.and_then(serde_json::Value::as_bool)
|
||||
.unwrap_or(false),
|
||||
}
|
||||
}
|
||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
let AstKind::TSEnumMember(decl) = node.kind() else { return };
|
||||
let Some(initializer) = &decl.initializer else { return };
|
||||
if initializer.is_literal() {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Expression::TemplateLiteral(template) = initializer {
|
||||
if template.expressions.len() == 0 {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if let Expression::UnaryExpression(unary_expr) = initializer {
|
||||
if unary_expr.argument.is_literal() {
|
||||
if matches!(
|
||||
unary_expr.operator,
|
||||
UnaryOperator::UnaryPlus | UnaryOperator::UnaryNegation,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.allow_bitwise_expressions
|
||||
&& matches!(unary_expr.operator, UnaryOperator::BitwiseNot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.allow_bitwise_expressions {
|
||||
if let Expression::BinaryExpression(binary_expr) = initializer {
|
||||
if matches!(
|
||||
binary_expr.operator,
|
||||
BinaryOperator::BitwiseOR
|
||||
| BinaryOperator::BitwiseAnd
|
||||
| BinaryOperator::BitwiseXOR
|
||||
| BinaryOperator::ShiftLeft
|
||||
| BinaryOperator::ShiftRight
|
||||
| BinaryOperator::ShiftRightZeroFill
|
||||
) && binary_expr.left.is_literal()
|
||||
&& binary_expr.right.is_literal()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.diagnostic(PreferLiteralEnumMemberDiagnostic(decl.span));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::tester::Tester;
|
||||
|
||||
let pass = vec![
|
||||
(
|
||||
"
|
||||
enum ValidRegex {
|
||||
A = /test/,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum ValidString {
|
||||
A = 'test',
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum ValidLiteral {
|
||||
A = `test`,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum ValidNumber {
|
||||
A = 42,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum ValidNumber {
|
||||
A = -42,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum ValidNumber {
|
||||
A = +42,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum ValidNull {
|
||||
A = null,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum ValidPlain {
|
||||
A,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum ValidQuotedKey {
|
||||
'a',
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum ValidQuotedKeyWithAssignment {
|
||||
'a' = 1,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum Foo {
|
||||
A = 1 << 0,
|
||||
B = 1 >> 0,
|
||||
C = 1 >>> 0,
|
||||
D = 1 | 0,
|
||||
E = 1 & 0,
|
||||
F = 1 ^ 0,
|
||||
G = ~1,
|
||||
}
|
||||
",
|
||||
Some(serde_json::json!([{ "allowBitwiseExpressions": true }])),
|
||||
),
|
||||
];
|
||||
|
||||
let fail = vec![
|
||||
(
|
||||
"
|
||||
enum InvalidObject {
|
||||
A = {},
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum InvalidArray {
|
||||
A = [],
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum InvalidTemplateLiteral {
|
||||
A = `foo ${0}`,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum InvalidConstructor {
|
||||
A = new Set(),
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum InvalidExpression {
|
||||
A = 2 + 2,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum InvalidExpression {
|
||||
A = delete 2,
|
||||
B = -a,
|
||||
C = void 2,
|
||||
D = ~2,
|
||||
E = !0,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
const variable = 'Test';
|
||||
enum InvalidVariable {
|
||||
A = 'TestStr',
|
||||
B = 2,
|
||||
C,
|
||||
V = variable,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum InvalidEnumMember {
|
||||
A = 'TestStr',
|
||||
B = A,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
const Valid = { A: 2 };
|
||||
enum InvalidObjectMember {
|
||||
A = 'TestStr',
|
||||
B = Valid.A,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum Valid {
|
||||
A,
|
||||
}
|
||||
enum InvalidEnumMember {
|
||||
A = 'TestStr',
|
||||
B = Valid.A,
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
const obj = { a: 1 };
|
||||
enum InvalidSpread {
|
||||
A = 'TestStr',
|
||||
B = { ...a },
|
||||
}
|
||||
",
|
||||
None,
|
||||
),
|
||||
(
|
||||
"
|
||||
enum Foo {
|
||||
A = 1 << 0,
|
||||
B = 1 >> 0,
|
||||
C = 1 >>> 0,
|
||||
D = 1 | 0,
|
||||
E = 1 & 0,
|
||||
F = 1 ^ 0,
|
||||
G = ~1,
|
||||
}
|
||||
",
|
||||
Some(serde_json::json!([{ "allowBitwiseExpressions": false }])),
|
||||
),
|
||||
(
|
||||
"
|
||||
const x = 1;
|
||||
enum Foo {
|
||||
A = x << 0,
|
||||
B = x >> 0,
|
||||
C = x >>> 0,
|
||||
D = x | 0,
|
||||
E = x & 0,
|
||||
F = x ^ 0,
|
||||
G = ~x,
|
||||
}
|
||||
",
|
||||
Some(serde_json::json!([{ "allowBitwiseExpressions": true }])),
|
||||
),
|
||||
];
|
||||
|
||||
Tester::new(PreferLiteralEnumMember::NAME, pass, fail).test_and_snapshot();
|
||||
}
|
||||
264
crates/oxc_linter/src/snapshots/prefer_literal_enum_member.snap
Normal file
264
crates/oxc_linter/src/snapshots/prefer_literal_enum_member.snap
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
---
|
||||
source: crates/oxc_linter/src/tester.rs
|
||||
expression: prefer_literal_enum_member
|
||||
---
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:3:12]
|
||||
2 │ enum InvalidObject {
|
||||
3 │ A = {},
|
||||
· ──────
|
||||
4 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:3:12]
|
||||
2 │ enum InvalidArray {
|
||||
3 │ A = [],
|
||||
· ──────
|
||||
4 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:3:12]
|
||||
2 │ enum InvalidTemplateLiteral {
|
||||
3 │ A = `foo ${0}`,
|
||||
· ──────────────
|
||||
4 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:3:12]
|
||||
2 │ enum InvalidConstructor {
|
||||
3 │ A = new Set(),
|
||||
· ─────────────
|
||||
4 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:3:12]
|
||||
2 │ enum InvalidExpression {
|
||||
3 │ A = 2 + 2,
|
||||
· ─────────
|
||||
4 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:3:12]
|
||||
2 │ enum InvalidExpression {
|
||||
3 │ A = delete 2,
|
||||
· ────────────
|
||||
4 │ B = -a,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:4:12]
|
||||
3 │ A = delete 2,
|
||||
4 │ B = -a,
|
||||
· ──────
|
||||
5 │ C = void 2,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:5:12]
|
||||
4 │ B = -a,
|
||||
5 │ C = void 2,
|
||||
· ──────────
|
||||
6 │ D = ~2,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:6:12]
|
||||
5 │ C = void 2,
|
||||
6 │ D = ~2,
|
||||
· ──────
|
||||
7 │ E = !0,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:7:12]
|
||||
6 │ D = ~2,
|
||||
7 │ E = !0,
|
||||
· ──────
|
||||
8 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:7:12]
|
||||
6 │ C,
|
||||
7 │ V = variable,
|
||||
· ────────────
|
||||
8 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:4:12]
|
||||
3 │ A = 'TestStr',
|
||||
4 │ B = A,
|
||||
· ─────
|
||||
5 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:5:12]
|
||||
4 │ A = 'TestStr',
|
||||
5 │ B = Valid.A,
|
||||
· ───────────
|
||||
6 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:7:12]
|
||||
6 │ A = 'TestStr',
|
||||
7 │ B = Valid.A,
|
||||
· ───────────
|
||||
8 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:5:12]
|
||||
4 │ A = 'TestStr',
|
||||
5 │ B = { ...a },
|
||||
· ────────────
|
||||
6 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:3:12]
|
||||
2 │ enum Foo {
|
||||
3 │ A = 1 << 0,
|
||||
· ──────────
|
||||
4 │ B = 1 >> 0,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:4:12]
|
||||
3 │ A = 1 << 0,
|
||||
4 │ B = 1 >> 0,
|
||||
· ──────────
|
||||
5 │ C = 1 >>> 0,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:5:12]
|
||||
4 │ B = 1 >> 0,
|
||||
5 │ C = 1 >>> 0,
|
||||
· ───────────
|
||||
6 │ D = 1 | 0,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:6:12]
|
||||
5 │ C = 1 >>> 0,
|
||||
6 │ D = 1 | 0,
|
||||
· ─────────
|
||||
7 │ E = 1 & 0,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:7:12]
|
||||
6 │ D = 1 | 0,
|
||||
7 │ E = 1 & 0,
|
||||
· ─────────
|
||||
8 │ F = 1 ^ 0,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:8:12]
|
||||
7 │ E = 1 & 0,
|
||||
8 │ F = 1 ^ 0,
|
||||
· ─────────
|
||||
9 │ G = ~1,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:9:12]
|
||||
8 │ F = 1 ^ 0,
|
||||
9 │ G = ~1,
|
||||
· ──────
|
||||
10 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:4:12]
|
||||
3 │ enum Foo {
|
||||
4 │ A = x << 0,
|
||||
· ──────────
|
||||
5 │ B = x >> 0,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:5:12]
|
||||
4 │ A = x << 0,
|
||||
5 │ B = x >> 0,
|
||||
· ──────────
|
||||
6 │ C = x >>> 0,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:6:12]
|
||||
5 │ B = x >> 0,
|
||||
6 │ C = x >>> 0,
|
||||
· ───────────
|
||||
7 │ D = x | 0,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:7:12]
|
||||
6 │ C = x >>> 0,
|
||||
7 │ D = x | 0,
|
||||
· ─────────
|
||||
8 │ E = x & 0,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:8:12]
|
||||
7 │ D = x | 0,
|
||||
8 │ E = x & 0,
|
||||
· ─────────
|
||||
9 │ F = x ^ 0,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:9:12]
|
||||
8 │ E = x & 0,
|
||||
9 │ F = x ^ 0,
|
||||
· ─────────
|
||||
10 │ G = ~x,
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
|
||||
⚠ typescript-eslint(prefer-literal-enum-member): Explicit enum value must only be a literal value (string, number, boolean, etc).
|
||||
╭─[prefer_literal_enum_member.tsx:10:12]
|
||||
9 │ F = x ^ 0,
|
||||
10 │ G = ~x,
|
||||
· ──────
|
||||
11 │ }
|
||||
╰────
|
||||
help: Require all enum members to be literal values.
|
||||
Loading…
Reference in a new issue