From 12440f3de6eb89ad2f636511ca4e8840051c743b Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Thu, 15 Jun 2023 17:45:50 -0400 Subject: [PATCH] feat(remix-eslint-config): extend from typescript-eslint/recommended (#6614) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Josh Goldberg ✨ --- .changeset/typescript-eslint-recommended.md | 5 ++ packages/remix-dev/__tests__/cli-test.ts | 2 +- .../compiler/server/plugins/bareImports.ts | 3 +- packages/remix-dev/server-build.ts | 1 - packages/remix-eslint-config/index.js | 9 ++- packages/remix-eslint-config/internal.js | 4 ++ packages/remix-eslint-config/rules/core.js | 1 - packages/remix-eslint-config/rules/import.js | 1 + .../remix-eslint-config/rules/typescript.js | 59 +++++++++---------- .../remix-netlify/__tests__/server-test.ts | 4 -- packages/remix-node/__tests__/fetch-test.ts | 1 - .../__tests__/deferred-scripts-test.tsx | 3 +- .../__tests__/serialize-test.ts | 3 +- packages/remix-server-runtime/responses.ts | 7 +-- 14 files changed, 49 insertions(+), 54 deletions(-) create mode 100644 .changeset/typescript-eslint-recommended.md diff --git a/.changeset/typescript-eslint-recommended.md b/.changeset/typescript-eslint-recommended.md new file mode 100644 index 00000000000..84c8ccac0ff --- /dev/null +++ b/.changeset/typescript-eslint-recommended.md @@ -0,0 +1,5 @@ +--- +"@remix-run/eslint-config": minor +--- + +Update `@remix-run/eslint-config` to inherit rules from `@typescript-eslint/recommended` diff --git a/packages/remix-dev/__tests__/cli-test.ts b/packages/remix-dev/__tests__/cli-test.ts index 91d8fea10b5..458cf17ec60 100644 --- a/packages/remix-dev/__tests__/cli-test.ts +++ b/packages/remix-dev/__tests__/cli-test.ts @@ -289,7 +289,7 @@ function defer() { async function interactWithShell( proc: childProcess.ChildProcessWithoutNullStreams, qAndA: Array< - | { question: RegExp; type: Array; answer?: never } + | { question: RegExp; type: Array; answer?: never } | { question: RegExp; answer: RegExp; type?: never } > ) { diff --git a/packages/remix-dev/compiler/server/plugins/bareImports.ts b/packages/remix-dev/compiler/server/plugins/bareImports.ts index 3d15801f390..75c95a1d45b 100644 --- a/packages/remix-dev/compiler/server/plugins/bareImports.ts +++ b/packages/remix-dev/compiler/server/plugins/bareImports.ts @@ -1,7 +1,6 @@ -import path from "path"; +import path, { isAbsolute, relative } from "path"; import fs from "fs"; import { builtinModules } from "module"; -import { isAbsolute, relative } from "path"; import type { Plugin } from "esbuild"; import { diff --git a/packages/remix-dev/server-build.ts b/packages/remix-dev/server-build.ts index d9144b95fe1..2098896e6f5 100644 --- a/packages/remix-dev/server-build.ts +++ b/packages/remix-dev/server-build.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-unreachable */ import type { ServerBuild } from "@remix-run/server-runtime"; throw new Error( diff --git a/packages/remix-eslint-config/index.js b/packages/remix-eslint-config/index.js index 660bb16fa95..2b5ec34853d 100644 --- a/packages/remix-eslint-config/index.js +++ b/packages/remix-eslint-config/index.js @@ -62,15 +62,14 @@ const config = { overrides: [ { files: ["**/*.ts?(x)"], - extends: ["plugin:import/typescript"], + extends: [ + "plugin:import/typescript", + "plugin:@typescript-eslint/recommended", + ], parser: "@typescript-eslint/parser", parserOptions: { sourceType: "module", ecmaVersion: 2019, - ecmaFeatures: { - jsx: true, - }, - warnOnUnsupportedTypeScriptVersion: true, }, plugins: ["@typescript-eslint"], rules: { diff --git a/packages/remix-eslint-config/internal.js b/packages/remix-eslint-config/internal.js index aade8adb1b5..f4ce0902732 100644 --- a/packages/remix-eslint-config/internal.js +++ b/packages/remix-eslint-config/internal.js @@ -67,6 +67,7 @@ module.exports = { // all ```ts & ```tsx code blocks in .md files files: ["**/*.md/*.ts?(x)"], rules: { + "import/no-duplicates": "off", "@typescript-eslint/no-unused-expressions": OFF, "@typescript-eslint/no-unused-vars": OFF, }, @@ -84,6 +85,9 @@ module.exports = { env: { "jest/globals": false, }, + rules: { + "import/no-duplicates": "off", + }, }, ], }; diff --git a/packages/remix-eslint-config/rules/core.js b/packages/remix-eslint-config/rules/core.js index aff9275c304..4da8a821cb9 100644 --- a/packages/remix-eslint-config/rules/core.js +++ b/packages/remix-eslint-config/rules/core.js @@ -56,7 +56,6 @@ module.exports = { "no-duplicate-case": WARN, "no-empty-character-class": WARN, "no-empty-pattern": WARN, - "no-duplicate-imports": WARN, "no-empty": [WARN, { allowEmptyCatch: true }], "no-eval": ERROR, "no-ex-assign": WARN, diff --git a/packages/remix-eslint-config/rules/import.js b/packages/remix-eslint-config/rules/import.js index b98e759d545..1b7d20e4d39 100644 --- a/packages/remix-eslint-config/rules/import.js +++ b/packages/remix-eslint-config/rules/import.js @@ -5,5 +5,6 @@ const ERROR = 2; module.exports = { "import/first": ERROR, "import/no-amd": ERROR, + "import/no-duplicates": ERROR, "import/no-webpack-loader-syntax": ERROR, }; diff --git a/packages/remix-eslint-config/rules/typescript.js b/packages/remix-eslint-config/rules/typescript.js index f81d2f1280d..3ce6a83f9f0 100644 --- a/packages/remix-eslint-config/rules/typescript.js +++ b/packages/remix-eslint-config/rules/typescript.js @@ -1,30 +1,20 @@ -const OFF = 0; -const WARN = 1; -const ERROR = 2; - module.exports = { - "no-dupe-class-members": OFF, - "no-undef": OFF, - - // Add TypeScript specific rules (and turn off ESLint equivalents) - "@typescript-eslint/consistent-type-assertions": WARN, - "@typescript-eslint/consistent-type-imports": WARN, - - "no-array-constructor": OFF, - "@typescript-eslint/no-array-constructor": WARN, - - // There is a bug w/ @typescript-eslint/no-duplicate-imports triggered - // by multiple imports inside of module declarations. We should reenable - // this rule when the bug is fixed. - // https://github.com/typescript-eslint/typescript-eslint/issues/3071 - "no-duplicate-imports": OFF, - // "@typescript-eslint/no-duplicate-imports": WARN, + // TODO: These rules might be nice to enable... we should investigate eventually! + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-empty-interface": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-var-requires": "off", + "no-var": "off", + "prefer-rest-params": "off", - "no-redeclare": OFF, - "@typescript-eslint/no-redeclare": ERROR, - "no-use-before-define": OFF, + // These rules are nice and we want to configure over the defaults "@typescript-eslint/no-use-before-define": [ - WARN, + "error", { functions: false, classes: false, @@ -32,23 +22,32 @@ module.exports = { typedefs: false, }, ], - "no-unused-expressions": OFF, "@typescript-eslint/no-unused-expressions": [ - WARN, + "error", { allowShortCircuit: true, allowTernary: true, allowTaggedTemplates: true, }, ], - "no-unused-vars": OFF, "@typescript-eslint/no-unused-vars": [ - WARN, + "error", { args: "none", ignoreRestSiblings: true, }, ], - "no-useless-constructor": OFF, - "@typescript-eslint/no-useless-constructor": WARN, + + // These rules are turned on in the core rules but aren't needed for TypeScript code + "no-dupe-class-members": "off", + "no-undef": "off", + + // These stylistic rules don't match our preferences + "no-use-before-define": "off", + "prefer-const": "off", + + // These rules should eventually come from @typescript-eslint/stylistic + // in typescript-eslint@6 + "@typescript-eslint/consistent-type-assertions": "warn", + "@typescript-eslint/consistent-type-imports": "warn", }; diff --git a/packages/remix-netlify/__tests__/server-test.ts b/packages/remix-netlify/__tests__/server-test.ts index 80fc451de8b..0b643a81410 100644 --- a/packages/remix-netlify/__tests__/server-test.ts +++ b/packages/remix-netlify/__tests__/server-test.ts @@ -2,10 +2,6 @@ import fsp from "fs/promises"; import path from "path"; import lambdaTester from "lambda-tester"; import { - // This has been added as a global in node 15+, but we expose it here while we - // support Node 14 - // eslint-disable-next-line @typescript-eslint/no-unused-vars - AbortController, createRequestHandler as createRemixRequestHandler, Response as NodeResponse, } from "@remix-run/node"; diff --git a/packages/remix-node/__tests__/fetch-test.ts b/packages/remix-node/__tests__/fetch-test.ts index 4fd79135ee5..6f7c8480662 100644 --- a/packages/remix-node/__tests__/fetch-test.ts +++ b/packages/remix-node/__tests__/fetch-test.ts @@ -1,4 +1,3 @@ -import { PassThrough } from "stream"; import { ReadableStream } from "@remix-run/web-stream"; import { Request } from "../fetch"; diff --git a/packages/remix-react/__tests__/deferred-scripts-test.tsx b/packages/remix-react/__tests__/deferred-scripts-test.tsx index 082377eccfb..b20a31d89ea 100644 --- a/packages/remix-react/__tests__/deferred-scripts-test.tsx +++ b/packages/remix-react/__tests__/deferred-scripts-test.tsx @@ -1,6 +1,5 @@ import * as React from "react"; -import { createMemoryRouter } from "react-router-dom"; -import { defer } from "react-router-dom"; +import { createMemoryRouter, defer } from "react-router-dom"; import { StaticRouterProvider } from "react-router-dom/server"; import { render } from "@testing-library/react"; import type { EntryContext } from "@remix-run/server-runtime"; diff --git a/packages/remix-server-runtime/__tests__/serialize-test.ts b/packages/remix-server-runtime/__tests__/serialize-test.ts index e5f606a6654..c3ed3fb1ac0 100644 --- a/packages/remix-server-runtime/__tests__/serialize-test.ts +++ b/packages/remix-server-runtime/__tests__/serialize-test.ts @@ -1,6 +1,5 @@ import type { SerializeFrom } from "../index"; -import { defer } from "../index"; -import { json } from "../index"; +import { defer, json } from "../index"; import type { IsNever } from "./utils"; import { isEqual } from "./utils"; diff --git a/packages/remix-server-runtime/responses.ts b/packages/remix-server-runtime/responses.ts index baf9128bf49..e26a706ccf7 100644 --- a/packages/remix-server-runtime/responses.ts +++ b/packages/remix-server-runtime/responses.ts @@ -24,17 +24,14 @@ export type DeferFunction = >( init?: number | ResponseInit ) => TypedDeferredData; -export type JsonFunction = ( +export type JsonFunction = ( data: Data, init?: number | ResponseInit ) => TypedResponse; // must be a type since this is a subtype of response // interfaces must conform to the types they extend -export type TypedResponse = Omit< - Response, - "json" -> & { +export type TypedResponse = Omit & { json(): Promise; };