-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(eslint): Manual rule setup with rule documentation (#108)
* Add setup section * More rule refactoring * Start documenting rules * Modularise * Remove js from extraFileExtensions * More documenting * Add more typescript rules/comments * Comment rule sources
- Loading branch information
1 parent
18b4f28
commit 920bffb
Showing
5 changed files
with
191 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// https://github.com/un-ts/eslint-plugin-import-x | ||
|
||
/** @type {import('eslint').Linter.FlatConfig} */ | ||
export const importRules = { | ||
name: 'tanstack/import', | ||
rules: { | ||
/** Stylistic preference */ | ||
'import/newline-after-import': 'error', | ||
/** No require() or module.exports */ | ||
'import/no-commonjs': 'error', | ||
/** No import loops */ | ||
'import/no-cycle': 'error', | ||
/** Reports if a resolved path is imported more than once */ | ||
'import/no-duplicates': 'error', | ||
/** Default export name cannot match named export */ | ||
'import/no-named-as-default': 'error', | ||
/** Don't access named imports from default export */ | ||
'import/no-named-as-default-member': 'error', | ||
/** Stylistic preference */ | ||
'import/order': [ | ||
'error', | ||
{ | ||
groups: [ | ||
'builtin', | ||
'external', | ||
'internal', | ||
'parent', | ||
'sibling', | ||
'index', | ||
'object', | ||
'type', | ||
], | ||
}, | ||
], | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,109 +1,36 @@ | ||
import tseslint from 'typescript-eslint' | ||
import pluginImport from 'eslint-plugin-import-x' | ||
import globals from 'globals' | ||
// @ts-expect-error | ||
import eslint from '@eslint/js' | ||
// @ts-expect-error | ||
import configPrettier from 'eslint-config-prettier' | ||
import { javascriptRules } from './javascript.js' | ||
import { importRules } from './import.js' | ||
import { typescriptRules } from './typescript.js' | ||
|
||
/** @type {import('eslint').Linter.FlatConfig[]} */ | ||
export const rootConfig = [ | ||
{ | ||
name: 'eslint/rules', | ||
rules: { | ||
...eslint.configs.recommended.rules, | ||
'no-async-promise-executor': 'off', | ||
'no-empty': 'off', | ||
'no-redeclare': 'off', | ||
'no-shadow': 'error', | ||
'no-undef': 'off', | ||
'sort-imports': ['error', { ignoreDeclarationSort: true }], | ||
}, | ||
}, | ||
{ | ||
name: 'prettier/rules', | ||
...configPrettier, | ||
}, | ||
...tseslint.configs.recommended, | ||
...tseslint.configs.stylistic, | ||
{ | ||
name: 'import/rules', | ||
plugins: { | ||
import: pluginImport, | ||
}, | ||
rules: { | ||
'import/newline-after-import': 'error', | ||
'import/no-cycle': 'error', | ||
'import/order': [ | ||
'error', | ||
{ | ||
groups: [ | ||
'builtin', | ||
'external', | ||
'internal', | ||
'parent', | ||
'sibling', | ||
'index', | ||
'object', | ||
'type', | ||
], | ||
}, | ||
], | ||
}, | ||
}, | ||
{ | ||
name: 'tanstack/custom', | ||
name: 'tanstack/setup', | ||
languageOptions: { | ||
globals: { | ||
...globals.browser, | ||
}, | ||
ecmaVersion: 2020, | ||
sourceType: 'module', | ||
ecmaVersion: 2020, | ||
// @ts-expect-error | ||
parser: tseslint.parser, | ||
parserOptions: { | ||
extraFileExtensions: ['.js', '.svelte', '.vue'], | ||
project: true, | ||
extraFileExtensions: ['.svelte', '.vue'], | ||
parser: tseslint.parser, | ||
}, | ||
globals: { | ||
...globals.browser, | ||
}, | ||
}, | ||
plugins: { | ||
'@typescript-eslint': tseslint.plugin, | ||
}, | ||
rules: { | ||
'@typescript-eslint/array-type': [ | ||
'error', | ||
{ default: 'generic', readonly: 'generic' }, | ||
], | ||
'@typescript-eslint/ban-types': 'off', | ||
'@typescript-eslint/ban-ts-comment': 'off', | ||
'@typescript-eslint/consistent-type-definitions': 'off', | ||
'@typescript-eslint/consistent-type-imports': [ | ||
'error', | ||
{ prefer: 'type-imports' }, | ||
], | ||
'@typescript-eslint/explicit-module-boundary-types': 'off', | ||
'@typescript-eslint/method-signature-style': ['error', 'property'], | ||
'@typescript-eslint/naming-convention': [ | ||
'error', | ||
{ | ||
selector: 'typeParameter', | ||
format: ['PascalCase'], | ||
leadingUnderscore: 'forbid', | ||
trailingUnderscore: 'forbid', | ||
custom: { | ||
regex: '^(T|T[A-Z][A-Za-z]+)$', | ||
match: true, | ||
}, | ||
}, | ||
], | ||
'@typescript-eslint/no-empty-interface': 'off', | ||
'@typescript-eslint/no-explicit-any': 'off', | ||
'@typescript-eslint/no-non-null-assertion': 'off', | ||
'@typescript-eslint/no-unnecessary-condition': 'error', | ||
'@typescript-eslint/no-unnecessary-type-assertion': 'error', | ||
'@typescript-eslint/no-unused-vars': 'off', | ||
'@typescript-eslint/no-inferrable-types': [ | ||
'error', | ||
{ ignoreParameters: true }, | ||
], | ||
// @ts-expect-error | ||
import: pluginImport, | ||
// @ts-expect-error | ||
ts: tseslint.plugin, | ||
}, | ||
}, | ||
javascriptRules, | ||
importRules, | ||
typescriptRules, | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// https://eslint.org/docs/latest/rules/ | ||
|
||
/** @type {import('eslint').Linter.FlatConfig} */ | ||
export const javascriptRules = { | ||
name: 'tanstack/javascript', | ||
rules: { | ||
/** Constructors of derived classes must call super() */ | ||
'constructor-super': 'error', | ||
/** TODO */ | ||
'for-direction': 'error', | ||
'getter-return': 'error', | ||
'no-async-promise-executor': 'error', | ||
'no-case-declarations': 'error', | ||
'no-class-assign': 'error', | ||
'no-compare-neg-zero': 'error', | ||
'no-cond-assign': 'error', | ||
'no-const-assign': 'error', | ||
'no-constant-binary-expression': 'error', | ||
'no-constant-condition': 'error', | ||
'no-control-regex': 'error', | ||
'no-debugger': 'error', | ||
'no-delete-var': 'error', | ||
'no-dupe-args': 'error', | ||
'no-dupe-class-members': 'error', | ||
'no-dupe-else-if': 'error', | ||
'no-dupe-keys': 'error', | ||
'no-duplicate-case': 'error', | ||
'no-empty': 'error', | ||
'no-empty-character-class': 'error', | ||
'no-empty-pattern': 'error', | ||
'no-empty-static-block': 'error', | ||
'no-ex-assign': 'error', | ||
'no-extra-boolean-cast': 'error', | ||
'no-fallthrough': 'error', | ||
'no-func-assign': 'error', | ||
'no-global-assign': 'error', | ||
'no-import-assign': 'error', | ||
'no-invalid-regexp': 'error', | ||
'no-irregular-whitespace': 'error', | ||
'no-loss-of-precision': 'error', | ||
'no-misleading-character-class': 'error', | ||
'no-new-native-nonconstructor': 'error', | ||
'no-nonoctal-decimal-escape': 'error', | ||
'no-obj-calls': 'error', | ||
'no-octal': 'error', | ||
'no-prototype-builtins': 'error', | ||
'no-redeclare': 'error', | ||
'no-regex-spaces': 'error', | ||
'no-self-assign': 'error', | ||
'no-setter-return': 'error', | ||
'no-shadow': 'error', | ||
'no-shadow-restricted-names': 'error', | ||
'no-sparse-arrays': 'error', | ||
'no-this-before-super': 'error', | ||
'no-unreachable': 'error', | ||
'no-unsafe-finally': 'error', | ||
'no-unsafe-negation': 'error', | ||
'no-unsafe-optional-chaining': 'error', | ||
'no-unused-labels': 'error', | ||
'no-unused-private-class-members': 'error', | ||
'no-unused-vars': 'error', | ||
'no-useless-backreference': 'error', | ||
'no-useless-catch': 'error', | ||
'no-useless-escape': 'error', | ||
/** Prefer let and const */ | ||
'no-var': 'error', | ||
'no-with': 'error', | ||
/** Prefer const if never re-assigned */ | ||
'prefer-const': 'error', | ||
'require-yield': 'error', | ||
/** Stylistic consistency */ | ||
'sort-imports': ['error', { ignoreDeclarationSort: true }], | ||
'use-isnan': 'error', | ||
/** Enforce comparing typeof against valid strings */ | ||
'valid-typeof': 'error', | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// https://typescript-eslint.io/rules/ | ||
|
||
/** @type {import('eslint').Linter.FlatConfig} */ | ||
export const typescriptRules = { | ||
name: 'tanstack/typescript', | ||
rules: { | ||
/** Prefer Array<T> format */ | ||
'ts/array-type': ['error', { default: 'generic', readonly: 'generic' }], | ||
/** Prevent @ts-ignore, allow @ts-expect-error */ | ||
'ts/ban-ts-comment': ['error', { 'ts-expect-error': false }], | ||
/** Bans specific built-in types and can suggest alternatives */ | ||
'ts/ban-types': 'error', | ||
/** Enforce import type { T } */ | ||
'ts/consistent-type-imports': ['error', { prefer: 'type-imports' }], | ||
/** Shorthand method style is less strict */ | ||
'ts/method-signature-style': ['error', 'property'], | ||
/** Enforces generic type convention */ | ||
'ts/naming-convention': [ | ||
'error', | ||
{ | ||
selector: 'typeParameter', | ||
format: ['PascalCase'], | ||
leadingUnderscore: 'forbid', | ||
trailingUnderscore: 'forbid', | ||
custom: { | ||
regex: '^(T|T[A-Z][A-Za-z]+)$', | ||
match: true, | ||
}, | ||
}, | ||
], | ||
/** Duplicate values can lead to bugs that are hard to track down */ | ||
'ts/no-duplicate-enum-values': 'error', | ||
/** Using the operator any more than once does nothing */ | ||
'ts/no-extra-non-null-assertion': 'error', | ||
/** There are several potential bugs with this compared to other loops */ | ||
'ts/no-for-in-array': 'error', | ||
/** Enforce valid definition of new and constructor */ | ||
'ts/no-misused-new': 'error', | ||
/** Disallow TypeScript namespaces */ | ||
'ts/no-namespace': 'error', | ||
/** Disallow non-null assertions after an optional chain expression */ | ||
'ts/no-non-null-asserted-optional-chain': 'error', | ||
/** Detects conditionals which will always evaluate truthy or falsy */ | ||
'ts/no-unnecessary-condition': 'error', | ||
/** Checks if the the explicit type is identical to the inferred type */ | ||
'ts/no-unnecessary-type-assertion': 'error', | ||
/** Don't over-define types for simple things like strings */ | ||
'ts/no-inferrable-types': ['error', { ignoreParameters: true }], | ||
/** Enforce the use of as const over literal type */ | ||
'ts/prefer-as-const': 'error', | ||
/** From recommended preset */ | ||
'ts/prefer-for-of': 'error', | ||
/** Disallow async functions which have no await expression */ | ||
'ts/require-await': 'error', | ||
/** Prefer of ES6-style import declarations */ | ||
'ts/triple-slash-reference': 'error', | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters