Skip to content

feat(eslint-plugin): [strict-enums] new rule #4864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 74 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
481fb44
feat: adding enums to member-ordering rule
Zamiell Apr 25, 2022
5776a01
Merge branch 'main' into strict-enums
Zamiell Apr 28, 2022
094c90e
feat(eslint-plugin): [strict-enums] adding check for null/undefined
Zamiell Apr 28, 2022
311b1f8
feat(eslint-plugin): [strict-enums] refactoring tests to separate files
Zamiell Apr 28, 2022
ac5e6d9
feat(eslint-plugin): [strict-enums] allowing more operators
Zamiell Apr 28, 2022
7d55248
fix(eslint-plugin): [strict-enums] adding union test
Zamiell Apr 29, 2022
74af3d1
fix(eslint-plugin): [strict-enums] refactoring + adding failing class
Zamiell Apr 29, 2022
1eb70ee
fix(eslint-plugin): [strict-enums] adding constraint code
Zamiell Apr 29, 2022
cf006fd
fix(eslint-plugin): [strict-enums] better eslint messages
Zamiell Apr 29, 2022
4d7f3fe
Merge branch 'main' into strict-enums
Zamiell Apr 29, 2022
2bbc2b7
fix(eslint-plugin): [strict-enums] removing vscode setting changes
Zamiell Apr 29, 2022
75c2252
Merge branch 'main' into strict-enums
Zamiell Apr 29, 2022
3976fdc
fix: changing function definition to reflect reality
Zamiell Apr 29, 2022
2406d03
fix: pass string enum literal into function that take string
Zamiell Apr 29, 2022
4244376
fix: allow passing enums to functions with any/unknown
Zamiell Apr 29, 2022
8b4dcdc
fix: using flags instead of names
Zamiell Apr 29, 2022
12f8120
fix: adding test that breaks the rule
Zamiell Apr 29, 2022
e638718
fix: adding test for variadic functions
Zamiell Apr 29, 2022
aef971a
fix: adding isSymbolFlagSet internally
Zamiell Apr 29, 2022
75f60b9
fix: adding ignoring for remaining lint failures
Zamiell Apr 30, 2022
d784aa0
fix: better comments
Zamiell Apr 30, 2022
811de98
fix: broken test
Zamiell Apr 30, 2022
9a71d45
fix: adding failing test for generic functions
Zamiell Apr 30, 2022
f93a02a
fix: refactoring tests + adding tests
Zamiell Apr 30, 2022
2ced9f8
fix: refactoring enum helper function locations
Zamiell Apr 30, 2022
0695c1b
fix: cleanup
Zamiell Apr 30, 2022
7272a95
fix: refactoring + fixing tests
Zamiell May 1, 2022
6ed1f66
fix: more tests
Zamiell May 1, 2022
83c70e3
fix: refactoring and making tests pass
Zamiell May 1, 2022
0ff3096
fix: adding array code, all tests pass now
Zamiell May 2, 2022
ddebded
fix: adding failing test
Zamiell May 2, 2022
c8b239b
fix: allow empty arrays
Zamiell May 2, 2022
90981a9
fix: adding logic for arrays with no enums
Zamiell May 2, 2022
32dec63
fix: adding more tests
Zamiell May 2, 2022
d0dbcbb
fix: fixing test
Zamiell May 2, 2022
c63c518
fix: fixing linter
Zamiell May 2, 2022
c5cf7f3
Merge branch 'main' into strict-enums
Zamiell May 2, 2022
1b26d74
Merge branch 'main' into strict-enums
Zamiell May 2, 2022
6e4f705
fix: reverting comment fixes
Zamiell May 3, 2022
a0a2ee6
fix: removing refactor
Zamiell May 3, 2022
dbae5db
fix: removing fixes to dot-notation
Zamiell May 3, 2022
16965d9
fix: removing semi refactor
Zamiell May 3, 2022
8b8f8f8
fix: removing jest logic
Zamiell May 3, 2022
5f437cc
fix: removing comparison operators check
Zamiell May 3, 2022
b1dbeb6
fix: adding failing test
Zamiell May 3, 2022
25caa05
fix: making test pass
Zamiell May 3, 2022
f42de61
fix: adding comment
Zamiell May 3, 2022
a866ddd
fix: adding back in bitwise operator checks since apparently they are
Zamiell May 3, 2022
61cf107
fix: remove bad comment
Zamiell May 3, 2022
304d796
fix: removing unnecessary comments
Zamiell May 3, 2022
83c5f30
fix: remove types from error messages
Zamiell May 3, 2022
23ac918
fix: removing isArray + refactoring
Zamiell May 4, 2022
098d732
Merge branch 'main' into strict-enums
Zamiell May 4, 2022
99424e1
Update packages/eslint-plugin/src/rules/strict-enums.ts
Zamiell May 4, 2022
0de3b26
fix: removing strict-enums from recommended
Zamiell May 4, 2022
2d488cc
fix: simplify
Zamiell May 5, 2022
15dc3df
fix: undoing refactoring
Zamiell May 6, 2022
a3d0122
fix: undoing refactoring
Zamiell May 6, 2022
5cd8fa7
fix: moving tests into subdirectory
Zamiell May 6, 2022
a236085
Update packages/eslint-plugin/src/rules/strict-enums.ts
Zamiell May 6, 2022
c357432
Update packages/eslint-plugin/src/rules/strict-enums.ts
Zamiell May 6, 2022
2395998
fix: adding failing test
Zamiell May 6, 2022
2851c3b
fix: making boolean tests pass
Zamiell May 6, 2022
149c049
Merge branch 'main' into strict-enums
Zamiell May 6, 2022
cf7c9b7
fix: refactor tests + fix linter
Zamiell May 6, 2022
3b2fa57
fix: adding brads tests
Zamiell May 6, 2022
6c43f71
fix: brads tests now pass
Zamiell May 6, 2022
af7d5da
Update packages/eslint-plugin/docs/rules/strict-enums.md
Zamiell May 7, 2022
a50f6e1
Merge branch 'main' into strict-enums
Zamiell May 10, 2022
85563be
Update packages/eslint-plugin/src/rules/strict-enums.ts
Zamiell May 30, 2022
ee96ce5
Update packages/eslint-plugin/src/rules/strict-enums.ts
Zamiell May 30, 2022
943bf9f
Update packages/eslint-plugin/src/rules/strict-enums.ts
Zamiell May 30, 2022
7679c4a
fix: make brads updates actually compile
Zamiell Jun 1, 2022
871e9ca
Update strict-enums.ts
Zamiell Jun 1, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/eslint-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ Pro Tip: For larger codebases you may want to consider splitting our linting int
| [`@typescript-eslint/restrict-template-expressions`](./docs/rules/restrict-template-expressions.md) | Enforce template literal expressions to be of string type | :white_check_mark: | | :thought_balloon: |
| [`@typescript-eslint/sort-type-union-intersection-members`](./docs/rules/sort-type-union-intersection-members.md) | Enforces that members of a type union/intersection are sorted alphabetically | | :wrench: | |
| [`@typescript-eslint/strict-boolean-expressions`](./docs/rules/strict-boolean-expressions.md) | Restricts the types allowed in boolean expressions | | :wrench: | :thought_balloon: |
| [`@typescript-eslint/strict-enums`](./docs/rules/strict-enums.md) | Disallows the usage of unsafe enum patterns | | | :thought_balloon: |
| [`@typescript-eslint/switch-exhaustiveness-check`](./docs/rules/switch-exhaustiveness-check.md) | Exhaustiveness checking in switch with union type | | | :thought_balloon: |
| [`@typescript-eslint/triple-slash-reference`](./docs/rules/triple-slash-reference.md) | Sets preference level for triple slash directives versus ES6-style import declarations | :white_check_mark: | | |
| [`@typescript-eslint/type-annotation-spacing`](./docs/rules/type-annotation-spacing.md) | Require consistent spacing around type annotations | | :wrench: | |
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/docs/rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ slug: /
| [`@typescript-eslint/restrict-template-expressions`](./restrict-template-expressions.md) | Enforce template literal expressions to be of string type | :white_check_mark: | | :thought_balloon: |
| [`@typescript-eslint/sort-type-union-intersection-members`](./sort-type-union-intersection-members.md) | Enforces that members of a type union/intersection are sorted alphabetically | | :wrench: | |
| [`@typescript-eslint/strict-boolean-expressions`](./strict-boolean-expressions.md) | Restricts the types allowed in boolean expressions | | :wrench: | :thought_balloon: |
| [`@typescript-eslint/strict-enums`](./docs/rules/strict-enums.md) | Disallows the usage of unsafe enum patterns | | | :thought_balloon: |
| [`@typescript-eslint/switch-exhaustiveness-check`](./switch-exhaustiveness-check.md) | Exhaustiveness checking in switch with union type | | | :thought_balloon: |
| [`@typescript-eslint/triple-slash-reference`](./triple-slash-reference.md) | Sets preference level for triple slash directives versus ES6-style import declarations | :white_check_mark: | | |
| [`@typescript-eslint/type-annotation-spacing`](./type-annotation-spacing.md) | Require consistent spacing around type annotations | | :wrench: | |
Expand Down
149 changes: 149 additions & 0 deletions packages/eslint-plugin/docs/rules/strict-enums.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# `strict-enums`

Disallows the usage of unsafe enum patterns.

## Rule Details

Horrifyingly, the TypeScript compiler will allow you to set any number to a variable containing a number enum, like this:

```ts
enum Fruit {
Apple,
Banana,
}

let fruit = Fruit.Apple;
fruit = 999; // No error
```

This has resulted in many TypeScript programmers avoiding the use of enums altogether. Instead, they should use this rule, which bans working with enums in potentially unsafe ways.

See the examples below for the types of patterns that are prevented.

## Goals

The goal of this rule is to make enums work like they do in other languages. One of the main benefits of enums is that they allow you to write code that is future-safe, because enums are supposed to be resilient to reorganization. If you arbitrarily change the values of an enum (or change the ordering of an enum with computed values), the idea is that nothing in your code-base should break.

## Banned Patterns

This rule bans:

1. Enum incrementing/decrementing - `incorrectIncrement`
1. Mismatched enum declarations/assignments - `mismatchedAssignment`
1. Mismatched enum comparisons - `mismatchedComparison`
1. Mismatched enum function arguments - `mismatchedFunctionArgument`
Comment on lines +27 to +34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is just a less-verbose duplicate of "Error Information" below - so let's remove this.


<!--tabs-->

### ❌ Incorrect

```ts
let fruit = Fruit.Apple;
fruit++;
```

```ts
const fruit: Fruit = 0;
```

```ts
if (fruit === 0) {
}
if (vegetable === 'lettuce') {
}
```

```ts
function useFruit(fruit: Fruit) {}
useFruit(0);
```

### ✅ Correct

```ts
let fruit = Fruit.Apple;
fruit = Fruit.Banana;
```

```ts
const fruit = Fruit.Apple;
```

```ts
let fruit = Fruit.Apple;
fruit = Fruit.Banana;
```

```ts
if (fruit === Fruit.Apple) {
}
if (vegetable === Vegetable.Lettuce) {
}
```

```ts
function useFruit(fruit: Fruit) {}
useFruit(Fruit.Apple);
```

## Error Information

- `incorrectIncrement` - You cannot increment or decrement an enum type.
- Enums are supposed to be resilient to reorganization, so you should explicitly assign a new value instead. For example, if someone someone reassigned/reordered the values of the enum, then it could potentially break your code.
- `mismatchedAssignment` - The type of the assignment does not match the declared enum type of the variable.
- In other words, you are trying to assign a `Foo` enum value to a variable with a `Bar` type. Enums are supposed to be resilient to reorganization, so these kinds of assignments can be dangerous.
- `mismatchedComparison` - The two things in the comparison do not have a shared enum type.
- You might be trying to compare using a number literal, like `Foo.Value1 === 1`. Or, you might be trying to compare use a disparate enum type, like `Foo.Value1 === Bar.Value1`. Either way, you need to use a value that corresponds to the correct enum, like `foo === Foo.Value1`, where `foo` is type `Foo`. Enums are supposed to be resilient to reorganization, so these types of comparisons can be dangerous.
- `mismatchedFunctionArgument` - The argument in the function call does not match the declared enum type of the function signature.
- You might be trying to use a number literal, like `useFoo(1)`. Or, you might be trying to use a disparate enum type, like `useFoo(Bar.Value1)`. Either way, you need to use a value that corresponds to the correct enum, like `useFoo(Foo.Value1)`. Enums are supposed to be resilient to reorganization, so non-exact function calls like this can be dangerous.

## Number Enums vs String Enums

Surprisingly, the TypeScript compiler deals with string enums in a safer way than it does with number enums. If we duplicate the first example above by using a string enum, the TypeScript compiler will correctly throw an error:

```ts
enum Vegetable {
Lettuce = 'lettuce',
Carrot = 'carrot',
}

let vegetable = Vegetable.Lettuce;
vegetable = 'definitelyNotAVegetable'; // Type '"definitelyNotAVegetable"' is not assignable to type 'Vegetable'.

// Even "valid" strings will not work, which is good!
vegetable = 'carrot'; // Type '"carrot"' is not assignable to type 'Vegetable'.
```

Thus, the `strict-enums` rule is mostly concerned with throwing errors for misused number enums. However, it still prevents mismatched comparison, which slips by the TypeScript compiler even for string enums:

```ts
// Bad
if (vegetable === 'lettuce') {
// The TypeScript compiler allows this, but the `strict-enums` rule does not
}

// Good
if (vegetable === Vegetable.Lettuce) {
}
```

## Comparison Operators

Since it is a common pattern, this rule allows using greater than or less than to compare numeric enums, like this:

```ts
if (fruit > Fruit.Banana) {
}
```

This pattern allows you to select a subset of enums. However, it can lead to bugs when enum values are arbitrarily changed, because the subset will also change. The TypeScript compiler cannot warn you about this, so you should use this pattern with care.

## Options

No options are provided.

## Attributes

- [ ] ✅ Recommended
- [ ] 🔧 Fixable
- [x] 💭 Requires type information
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/configs/all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ export = {
'space-infix-ops': 'off',
'@typescript-eslint/space-infix-ops': 'error',
'@typescript-eslint/strict-boolean-expressions': 'error',
'@typescript-eslint/strict-enums': 'error',
'@typescript-eslint/switch-exhaustiveness-check': 'error',
'@typescript-eslint/triple-slash-reference': 'error',
'@typescript-eslint/type-annotation-spacing': 'error',
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-plugin/src/rules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ import spaceBeforeBlocks from './space-before-blocks';
import spaceBeforeFunctionParen from './space-before-function-paren';
import spaceInfixOps from './space-infix-ops';
import strictBooleanExpressions from './strict-boolean-expressions';
import strictEnums from './strict-enums';
import switchExhaustivenessCheck from './switch-exhaustiveness-check';
import tripleSlashReference from './triple-slash-reference';
import typeAnnotationSpacing from './type-annotation-spacing';
Expand Down Expand Up @@ -246,6 +247,7 @@ export default {
'space-before-function-paren': spaceBeforeFunctionParen,
'space-infix-ops': spaceInfixOps,
'strict-boolean-expressions': strictBooleanExpressions,
'strict-enums': strictEnums,
'switch-exhaustiveness-check': switchExhaustivenessCheck,
'triple-slash-reference': tripleSlashReference,
'type-annotation-spacing': typeAnnotationSpacing,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { AST_NODE_TYPES, TSESLint, TSESTree } from '@typescript-eslint/utils';
import * as tsutils from 'tsutils';
import * as ts from 'typescript';
import * as util from '../util';

Expand Down Expand Up @@ -82,7 +81,7 @@ export default util.createRule<Options, MessageId>({
const checker = parserServices.program.getTypeChecker();
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
const type = util.getConstrainedTypeAtLocation(checker, tsNode);
if (!tsutils.isTypeFlagSet(type, ts.TypeFlags.VoidLike)) {
if (!util.isTypeFlagSet(type, ts.TypeFlags.VoidLike)) {
// not a void expression
return;
}
Expand Down
3 changes: 2 additions & 1 deletion packages/eslint-plugin/src/rules/no-empty-interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as util from '../util';
import { TSESLint } from '@typescript-eslint/utils';
import { ScopeType } from '@typescript-eslint/scope-manager';

type Options = [
{
Expand Down Expand Up @@ -78,7 +79,7 @@ export default util.createRule<Options, MessageIds>({
let useAutoFix = true;
if (util.isDefinitionFile(filename)) {
const scope = context.getScope();
if (scope.type === 'tsModule' && scope.block.declare) {
if (scope.type === ScopeType.tsModule && scope.block.declare) {
useAutoFix = false;
}
}
Expand Down
3 changes: 1 addition & 2 deletions packages/eslint-plugin/src/rules/no-implied-eval.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as ts from 'typescript';
import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/utils';
import * as tsutils from 'tsutils';
import * as util from '../util';

const FUNCTION_CONSTRUCTOR = 'Function';
Expand Down Expand Up @@ -69,7 +68,7 @@ export default util.createRule({

if (
symbol &&
tsutils.isSymbolFlagSet(
util.isSymbolFlagSet(
symbol,
ts.SymbolFlags.Function | ts.SymbolFlags.Method,
)
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/rules/no-misused-promises.ts
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ function isVoidReturningFunctionType(
return false;
}

hadVoidReturn ||= tsutils.isTypeFlagSet(returnType, ts.TypeFlags.Void);
hadVoidReturn ||= util.isTypeFlagSet(returnType, ts.TypeFlags.Void);
}
}

Expand Down
3 changes: 2 additions & 1 deletion packages/eslint-plugin/src/rules/no-redeclare.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ScopeType } from '@typescript-eslint/scope-manager';
import { TSESTree, TSESLint, AST_NODE_TYPES } from '@typescript-eslint/utils';
import * as util from '../util';

Expand Down Expand Up @@ -254,7 +255,7 @@ export default util.createRule<Options, MessageIds>({

// Node.js or ES modules has a special scope.
if (
scope.type === 'global' &&
scope.type === ScopeType.global &&
scope.childScopes[0] &&
// The special scope's block is the Program node.
scope.block === scope.childScopes[0].block
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils';
import * as tsutils from 'tsutils';
import * as ts from 'typescript';
import * as util from '../util';

Expand Down Expand Up @@ -107,7 +106,7 @@ export default util.createRule<Options, MessageIds>({
}

function isBooleanType(expressionType: ts.Type): boolean {
return tsutils.isTypeFlagSet(
return util.isTypeFlagSetSimple(
expressionType,
ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral,
);
Expand All @@ -128,7 +127,7 @@ export default util.createRule<Options, MessageIds>({

const nonNullishTypes = types.filter(
type =>
!tsutils.isTypeFlagSet(
!util.isTypeFlagSetSimple(
type,
ts.TypeFlags.Undefined | ts.TypeFlags.Null,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ export default createRule<Options, MessageId>({
if (isStrictNullChecks) {
const UNDEFINED = ts.TypeFlags.Undefined;
const NULL = ts.TypeFlags.Null;
const isComparable = (type: ts.Type, flag: ts.TypeFlags): boolean => {
const isComparable = (type: ts.Type, flag: number): boolean => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes the function parameter less precise. I don't think we'd want that. See my comment in typeFlagUtils.ts.

// Allow comparison to `any`, `unknown` or a naked type parameter.
flag |=
ts.TypeFlags.Any |
Expand Down
3 changes: 1 addition & 2 deletions packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils';
import * as ts from 'typescript';
import * as tsutils from 'tsutils';
import * as util from '../util';

export default util.createRule({
Expand Down Expand Up @@ -33,7 +32,7 @@ export default util.createRule({
symbol: ts.Symbol,
checker: ts.TypeChecker,
): ts.Symbol | null {
return tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)
return util.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)
? checker.getAliasedSymbol(symbol)
: null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { TSESTree } from '@typescript-eslint/utils';
import * as tsutils from 'tsutils';
import * as ts from 'typescript';
import * as util from '../util';
import { findFirstResult } from '../util';
Expand Down Expand Up @@ -179,7 +178,7 @@ function getAliasedSymbol(
symbol: ts.Symbol,
checker: ts.TypeChecker,
): ts.Symbol {
return tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)
return util.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)
? checker.getAliasedSymbol(symbol)
: symbol;
}
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/rules/no-use-before-define.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function isOuterEnum(
reference: TSESLint.Scope.Reference,
): boolean {
return (
variable.defs[0].type == DefinitionType.TSEnumName &&
variable.defs[0].type === DefinitionType.TSEnumName &&
variable.scope.variableScope !== reference.from.variableScope
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils';
import * as tsutils from 'tsutils';
import * as ts from 'typescript';

import * as util from '../util';

export default util.createRule({
Expand Down Expand Up @@ -34,9 +33,7 @@ export default util.createRule({
parserServices.esTreeNodeToTSNodeMap.get(node),
);

if (
tsutils.isTypeFlagSet(type, ts.TypeFlags.Any | ts.TypeFlags.Unknown)
) {
if (util.isTypeFlagSet(type, ts.TypeFlags.Any | ts.TypeFlags.Unknown)) {
return undefined;
}

Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/rules/return-await.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export default util.createRule({
ts.SyntaxKind.AwaitExpression,
ts.SyntaxKind.Unknown,
);

return nodePrecedence > awaitPrecedence;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AST_NODE_TYPES, TSESLint, TSESTree } from '@typescript-eslint/utils';
import { getEnumNames } from '@typescript-eslint/type-utils';
import * as util from '../util';
import { getEnumNames } from '../util';

enum Group {
conditional = 'conditional',
Expand Down
Loading