@fluidframework/eslint-config-fluid
Version:
Shareable ESLint config for the Fluid Framework
217 lines (179 loc) • 7.35 kB
text/typescript
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Recommended ESLint rules.
*
* This module contains rules that extend the base configuration.
* The recommended config adds stricter type safety rules, unicorn/recommended overrides,
* and enables rules that were disabled at lower levels. This is the standard config
* for most Fluid Framework packages.
*/
import type { Linter } from "eslint";
/**
* Rules from recommended.js.
*/
export const recommendedRules = {
"@rushstack/no-new-null": "error",
"no-void": "error",
"require-atomic-updates": "error",
// #region `unicorn` rule overrides
// TODO: Enable this rule and fix violations once eslint9 upgrade is done
"unicorn/consistent-function-scoping": "warn",
/**
* TODO: Consider enabling in the future.
*/
"unicorn/import-style": "off",
// False positives on non-array `push` methods.
"unicorn/no-array-push-push": "off",
// False positives on non-array methods.
"unicorn/no-array-callback-reference": "off",
"unicorn/empty-brace-spaces": "off",
// Rationale: Destructuring of `Array.entries()` in order to get the index variable results in a
// significant performance regression [node 14 x64].
"unicorn/no-for-loop": "off",
/**
* Disabled because we will lean on the formatter (i.e. prettier) to enforce indentation policy.
* @remarks This rule also directly conflicts with prettier's formatting of nested ternary expressions.
*/
"unicorn/no-nested-ternary": "off",
/**
* Disabled due to false positives / disruptive behavior of auto-fix.
* See {@link https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2018}.
* We may consider re-enabling once the above issue has been resolved.
*/
"unicorn/no-useless-spread": "off",
/**
* Disabled due to the sheer number of false positives it detects, and because it is sometimes valuable to
* explicitly denote `undefined`.
*/
"unicorn/no-useless-undefined": "off",
/**
* By default, this rule conflicts with our internal error code formats.
* Only enforce `_` separator consistency if any such separators appear in the number literal.
*/
"unicorn/numeric-separators-style": ["error", { onlyIfContainsSeparator: true }],
"unicorn/prevent-abbreviations": "off",
/**
* Enable in a future update; warning for now to surface occurrences without breaking builds.
*/
"unicorn/prefer-at": "warn",
/**
* Disabled because we use EventEmitter everywhere today and changing it will be a bigger change outside of lint
* rules.
*/
"unicorn/prefer-event-target": "off",
/**
* TODO: Enable in a future update; warning for now to surface occurrences without breaking builds.
*/
"unicorn/prefer-string-raw": "warn",
/**
* TODO: Enable in a future update; warning for now to surface occurrences without breaking builds.
*/
"unicorn/prefer-string-replace-all": "warn",
/**
* TODO: Enable in a future update; warning for now to surface occurrences without breaking builds.
*/
"unicorn/prefer-structured-clone": "warn",
/**
* Disabled because we will lean on the formatter (i.e. prettier) to enforce indentation policy.
*/
"unicorn/template-indent": "off",
/**
* Disabled because it is incompatible with prettier.
*/
"unicorn/number-literal-case": "off",
/**
* The rule seems to crash on some of our code
*/
"unicorn/expiring-todo-comments": "off",
// #endregion
/**
* Disallows the `any` type.
* Using the `any` type defeats the purpose of using TypeScript.
* When `any` is used, all compiler type checks around that value are ignored.
*
* @see https://typescript-eslint.io/rules/no-explicit-any
*/
"@typescript-eslint/no-explicit-any": [
"error",
{
/**
* For certain cases, like rest parameters, any is required to allow arbitrary argument types.
* @see https://typescript-eslint.io/rules/no-explicit-any/#ignorerestargs
*/
ignoreRestArgs: true,
},
],
/**
* Requires explicit typing for anything exported from a module. Explicit types for function return
* values and arguments makes it clear to any calling code what is the module boundary's input and
* output.
*/
"@typescript-eslint/explicit-module-boundary-types": "error",
/**
* Disallows calling a function with a value with type `any`.
* Despite your best intentions, the `any` type can sometimes leak into your codebase.
* Call a function with `any` typed argument are not checked at all by TypeScript, so it creates a
* potential safety hole, and source of bugs in your codebase.
*/
"@typescript-eslint/no-unsafe-argument": "error",
/**
* Disallows assigning any to a variable, and assigning any[] to an array destructuring. Assigning an
* any typed value to a variable can be hard to pick up on, particularly if it leaks in from an external
* library.
*/
"@typescript-eslint/no-unsafe-assignment": "error",
/**
* Disallows calling any variable that is typed as any. The arguments to, and return value of calling an
* `any`-typed variable are not checked at all by TypeScript.
*/
"@typescript-eslint/no-unsafe-call": "error",
/**
* Disallows member access on any variable that is typed as any. The arguments to, and return value of
* calling an `any`-typed variable are not checked at all by TypeScript.
*/
"@typescript-eslint/no-unsafe-member-access": "error",
/**
* Disallows returning a value with type any from a function.
*
* Despite your best intentions, the any type can sometimes leak into your codebase.
* Returned any typed values are not checked at all by TypeScript, so it creates a potential safety
* hole, and source of bugs in your codebase.
*/
"@typescript-eslint/no-unsafe-return": "error",
/**
* Requires eslint-disable comments to include a description explaining why the rule is being disabled.
*
* Docs: {@link https://eslint-community.github.io/eslint-plugin-eslint-comments/rules/require-description.html}
*/
"@eslint-community/eslint-comments/require-description": "warn",
// #region eslint-plugin-jsdoc rules
/**
* Require the description (summary) component in JSDoc/TSDoc comments
* See <https://github.com/gajus/eslint-plugin-jsdoc#user-content-eslint-plugin-jsdoc-rules-require-description>
*/
"jsdoc/require-description": ["error", { checkConstructors: false }],
// #endregion
/**
* Requires that type-only exports be done using `export type`. Being explicit allows the TypeScript
* `isolatedModules` flag to be used, and isolated modules are needed to adopt modern build tools like swc.
*
* @see {@link https://typescript-eslint.io/rules/consistent-type-exports/}
*/
"@typescript-eslint/consistent-type-exports": [
"error",
{
// Makes it easier to tell, at a glance, the impact of a change to individual exports.
fixMixedExportsWithInlineTypeSpecifier: true,
},
],
/**
* Requires that type-only imports be done using `import type`. Being explicit allows the TypeScript
* `isolatedModules` flag to be used, and isolated modules are needed to adopt modern build tools like swc.
*
* @see {@link https://typescript-eslint.io/rules/consistent-type-imports/}
*/
"@typescript-eslint/consistent-type-imports": ["error", { fixStyle: "separate-type-imports" }],
} as const satisfies Linter.RulesRecord;