Repository: babel/babel-eslint (JavaScript)

Issue:
Circular flow type definitions trigger no-use-before-define
Brought here from https://github.com/eslint/eslint/issues/8703, by @soda0289 request:
When using core rule `no-use-before-define`, default for example in `standard`, it is applied to type definitions.
This could be a good thing, but the current implementation gives an unavoidable error on circular definitions:

```js
/* @flow */
type File = {chunks: Array<Chunk>}
type Chunk = {file: File}
```
**produces**
```
.../src/commands.js
  2:21  error  'File' was used before it was defined  no-use-before-define

✖ 1 problem (1 error, 0 warnings)
```
**OR**
```js
/* @flow */
type Chunk = {file: File}
type File = {chunks: Array<Chunk>}
```
**produces**
```
.../src/commands.js
  2:28  error  'Chunk' was used before it was defined  no-use-before-define

✖ 1 problem (1 error, 0 warnings)
```
respectively.

Currently, disabling `no-use-before-define` in the files that have flow enabled (all for me) is a fix when actual flow is checked, since that catches undefined.
However, it is still probably a bug, since:
```js
// This is an actual error
const a = {b}
const b = {a}
// While this works and is often necessary
type A = {b:B}
type B = {a:A}
```



Discussion:
I worked around this by disabling the check inline:

```js
/* eslint-disable no-use-before-define */

export type GetState = () => State;
export type ThunkAction = (dispatch: Dispatch, getState: GetState) => any;
export type PromiseAction = Promise<Action>;
export type Dispatch = (action: Action | ThunkAction | PromiseAction) => any;

/* eslint-enable no-use-before-define */
```
Had to revert this because this was causing many issues in other rules due to the AST change in https://github.com/babel/babel-eslint/pull/697, https://github.com/babel/babel-eslint/releases/tag/v10.0.1
Tip for folks putting types in a `types/` (etc) specific directory, you might add an eslint config file to disable the rule for that directory:

```
// .eslintrc.js
module.exports = {
  'rules': {
    'no-use-before-define': 'off',
  },
};
```
Maybe add another option in config to allow type be ignored by this rule? Both flow and typescript.
Thank you for the issue. Now that [`@babel/eslint-parser` has been released](https://babeljs.io/blog/2020/07/13/the-state-of-babel-eslint), we are making this repository read-only. If this is a change you would still like to advocate for, please reopen this in the [babel/babel monorepo](https://github.com/babel/babel).



Patch:
diff --git a/lib/babylon-to-espree/toAST.js b/lib/babylon-to-espree/toAST.js
index b3da41f0..88349d7c 100644
--- a/lib/babylon-to-espree/toAST.js
+++ b/lib/babylon-to-espree/toAST.js
@@ -72,6 +72,15 @@ var astTransformVisitor = {
       delete node.bound;
     }
 
+    if (path.isTypeAlias()) {
+      node.type = "FunctionDeclaration";
+      node.generator = false;
+      node.async = false;
+      node.expression = false;
+      node.params = [];
+      node.body = node.right;
+    }
+
     // flow: prevent "no-undef"
     // for "Component" in: "let x: React.Component"
     if (path.isQualifiedTypeIdentifier()) {


Test patch:
diff --git a/test/non-regression.js b/test/non-regression.js
index db5bb59c..7cb61b85 100644
--- a/test/non-regression.js
+++ b/test/non-regression.js
@@ -1157,6 +1157,18 @@ describe("verify", () => {
         []
       );
     });
+
+    it("cyclic type dependencies #485", () => {
+      verifyAndAssertMessages(
+        unpad(`
+          type Node<T> = { head: T, tail: Node<T> };
+          type A = B[];
+          type B = number;
+        `),
+        { "no-use-before-define": 1 },
+        []
+      );
+    });
   });
 
   it("class usage", () => {