diff --git a/packages/eslint-plugin/docs/rules/ban-ts-ignore.md b/packages/eslint-plugin/docs/rules/ban-ts-ignore.md deleted file mode 100644 index 936d7936afc9..000000000000 --- a/packages/eslint-plugin/docs/rules/ban-ts-ignore.md +++ /dev/null @@ -1,44 +0,0 @@ -# Bans “// @ts-ignore” comments from being used (`ban-ts-ignore`) - -This rule has been deprecated in favor of [`ban-ts-comment`](./ban-ts-comment.md) - -Suppressing TypeScript Compiler Errors can be hard to discover. - -## DEPRECATED - -This rule has been deprecated in favour of the [`ban-ts-comment`](./ban-ts-comment.md) rule. -It will be removed in a future version of this plugin. - -## Rule Details - -Does not allow the use of `// @ts-ignore` comments. - -The following patterns are considered warnings: - -```ts -if (false) { - // @ts-ignore: Unreachable code error - console.log('hello'); -} -``` - -The following patterns are not warnings: - -```ts -if (false) { - // Compiler warns about unreachable code error - console.log('hello'); -} -``` - -## When Not To Use It - -If you are sure, compiler errors won't affect functionality and you need to disable them. - -## Further Reading - -- TypeScript [Type Checking JavaScript Files](https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html) - -## Compatibility - -- TSLint: [ban-ts-ignore](https://palantir.github.io/tslint/rules/ban-ts-ignore/) diff --git a/packages/eslint-plugin/docs/rules/camelcase.md b/packages/eslint-plugin/docs/rules/camelcase.md index 89cd63aa9295..cea28224965f 100644 --- a/packages/eslint-plugin/docs/rules/camelcase.md +++ b/packages/eslint-plugin/docs/rules/camelcase.md @@ -1,136 +1,8 @@ -# Enforce camelCase naming convention (`camelcase`) - ## DEPRECATED This rule has been deprecated in favour of the [`naming-convention`](./naming-convention.md) rule. -It will be removed in a future version of this plugin. - -## Rule Details - -This rule extends the base [`eslint/camelcase`](https://eslint.org/docs/rules/camelcase) rule. -It adds support for numerous TypeScript features. - -## How to use - -```jsonc -{ - // note you must disable the base rule as it can report incorrect errors - "camelcase": "off", - "@typescript-eslint/camelcase": ["error"] -} -``` - -## Options - -See [`eslint/camelcase` options](https://eslint.org/docs/rules/camelcase#options). -This rule adds the following options: - -```ts -interface Options extends BaseCamelcaseOptions { - genericType?: 'always' | 'never'; -} - -const defaultOptions: Options = { - ...baseCamelcaseDefaultOptions, - genericType: 'never', -}; -``` - -- `"genericType": "never"` (default) does not check generic identifiers -- `"genericType": "always"` enforces camelCase style for generic identifiers - -### `genericType: "always"` - -Examples of **incorrect** code for this rule with the default `{ "genericType": "always" }` option: - -```typescript -/* eslint @typescript-eslint/camelcase: ["error", { "genericType": "always" }] */ - -interface Foo {} -function foo() {} -class Foo {} -type Foo = {}; -class Foo { - method() {} -} - -interface Foo {} -function foo() {} -class Foo {} -type Foo = {}; -class Foo { - method() {} -} - -interface Foo {} -function foo() {} -class Foo {} -type Foo = {}; -class Foo { - method() {} -} -``` - -Examples of **correct** code for this rule with the default `{ "genericType": "always" }` option: - -```typescript -/* eslint @typescript-eslint/camelcase: ["error", { "genericType": "always" }] */ - -interface Foo {} -function foo() {} -class Foo {} -type Foo = {}; -class Foo { - method() {} -} - -interface Foo {} -function foo() {} -class Foo {} -type Foo = {}; -class Foo { - method() {} -} - -interface Foo {} -function foo() {} -class Foo {} -type Foo = {}; -class Foo { - method() {} -} -``` - -### `genericType: "never"` - -Examples of **correct** code for this rule with the `{ "genericType": "never" }` option: - -```typescript -/* eslint @typescript-eslint/camelcase: ["error", { "genericType": "never" }] */ - -interface Foo {} -function foo() {} -class Foo {} -type Foo = {}; -class Foo { - method() {} -} - -interface Foo {} -function foo() {} -class Foo {} -type Foo = {}; -class Foo { - method() {} -} - -interface Foo {} -function foo() {} -class Foo {} -type Foo = {}; -class Foo { - method() {} -} -``` -Taken with ❤️ [from ESLint core](https://github.com/eslint/eslint/blob/master/docs/rules/camelcase.md) + diff --git a/packages/eslint-plugin/docs/rules/class-name-casing.md b/packages/eslint-plugin/docs/rules/class-name-casing.md deleted file mode 100644 index ae5d5da7a2e6..000000000000 --- a/packages/eslint-plugin/docs/rules/class-name-casing.md +++ /dev/null @@ -1,61 +0,0 @@ -# Require PascalCased class and interface names (`class-name-casing`) - -This rule enforces PascalCase names for classes and interfaces. - -## DEPRECATED - -This rule has been deprecated in favour of the [`naming-convention`](./naming-convention.md) rule. -It will be removed in a future version of this plugin. - -## Rule Details - -This rule aims to make it easy to differentiate classes from regular variables at a glance. -The `_` prefix is sometimes used to designate a private declaration, so the rule also supports a name -that might be `_Example` instead of `Example`. - -## Options - -This rule has an object option: - -- `"allowUnderscorePrefix": false`: (default) does not allow the name to have an underscore prefix -- `"allowUnderscorePrefix": true`: allows the name to optionally have an underscore prefix - -## Examples - -Examples of **incorrect** code for this rule: - -```ts -class invalidClassName {} - -class Another_Invalid_Class_Name {} - -var bar = class invalidName {}; - -interface someInterface {} - -class _InternalClass {} -``` - -Examples of **correct** code for this rule: - -```ts -class ValidClassName {} - -export default class {} - -var foo = class {}; - -interface SomeInterface {} - -/* eslint @typescript-eslint/class-name-casing: { "allowUnderscorePrefix": true } */ -class _InternalClass {} -``` - -## When Not To Use It - -You should turn off this rule if you do not care about class name casing, or if -you use a different type of casing. - -## Further Reading - -- [`class-name`](https://palantir.github.io/tslint/rules/class-name/) in [TSLint](https://palantir.github.io/tslint/) diff --git a/packages/eslint-plugin/docs/rules/generic-type-naming.md b/packages/eslint-plugin/docs/rules/generic-type-naming.md deleted file mode 100644 index dc9642735359..000000000000 --- a/packages/eslint-plugin/docs/rules/generic-type-naming.md +++ /dev/null @@ -1,47 +0,0 @@ -# Enforces naming of generic type variables (`generic-type-naming`) - -It can be helpful to enforce a consistent naming style for generic type variables used within a type. -For example, prefixing them with `T` and ensuring a somewhat descriptive name, or enforcing Hungarian notation. - -## DEPRECATED - -This rule has been deprecated in favour of the [`naming-convention`](./naming-convention.md) rule. -It will be removed in a future version of this plugin. - -## Rule Details - -This rule allows you to enforce conventions over type variables. By default, it does nothing. - -## Options - -The rule takes a single string option, which is a regular expression that type variables should match. - -Examples of **correct** code with a configuration of `'^T[A-Z][a-zA-Z]+$'`: - -```ts -type ReadOnly = { - readonly [TKey in keyof TType]: TType[TKey]; -}; - -interface SimpleMap { - [key: string]: TValue; -} -``` - -Examples of **incorrect** code with a configuration of `'^T[A-Z][a-zA-Z]+$'`: - -```ts -type ReadOnly = { readonly [Key in keyof T]: T[Key] }; - -interface SimpleMap { - [key: string]: T; -} -``` - -## When Not To Use It - -If you do not want to enforce a naming convention for type variables. - -## Further Reading - -- [TypeScript Generics](https://www.typescriptlang.org/docs/handbook/generics.html) diff --git a/packages/eslint-plugin/docs/rules/interface-name-prefix.md b/packages/eslint-plugin/docs/rules/interface-name-prefix.md deleted file mode 100644 index 6322c9c79d65..000000000000 --- a/packages/eslint-plugin/docs/rules/interface-name-prefix.md +++ /dev/null @@ -1,141 +0,0 @@ -# Require that interface names should or should not prefixed with `I` (`interface-name-prefix`) - -Interfaces often represent important software contracts, so it can be helpful to prefix their names with `I`. -The unprefixed name is then available for a class that provides a standard implementation of the interface. -Alternatively, the contributor guidelines for the TypeScript repo suggest -[never prefixing](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#names) interfaces with `I`. - -## DEPRECATED - -This rule has been deprecated in favour of the [`naming-convention`](./naming-convention.md) rule. -It will be removed in a future version of this plugin. - -## Rule Details - -This rule enforces whether or not the `I` prefix is required for interface names. -The `_` prefix is sometimes used to designate a private declaration, so the rule also supports a private interface -that might be named `_IAnimal` instead of `IAnimal`. - -## Options - -This rule has an object option: - -- `{ "prefixWithI": "never" }`: (default) disallows all interfaces being prefixed with `"I"` or `"_I"` -- `{ "prefixWithI": "always" }`: requires all interfaces be prefixed with `"I"` (but does not allow `"_I"`) -- `{ "prefixWithI": "always", "allowUnderscorePrefix": true }`: requires all interfaces be prefixed with - either `"I"` or `"_I"` - -For backwards compatibility, this rule supports a string option instead: - -- `"never"`: Equivalent to `{ "prefixWithI": "never" }` -- `"always"`: Equivalent to `{ "prefixWithI": "always" }` - -## Examples - -### never - -**Configuration:** `{ "prefixWithI": "never" }` - -The following patterns are considered warnings: - -```ts -interface IAnimal { - name: string; -} - -interface IIguana { - name: string; -} - -interface _IAnimal { - name: string; -} -``` - -The following patterns are not warnings: - -```ts -interface Animal { - name: string; -} - -interface Iguana { - name: string; -} -``` - -### always - -**Configuration:** `{ "prefixWithI": "always" }` - -The following patterns are considered warnings: - -```ts -interface Animal { - name: string; -} - -interface Iguana { - name: string; -} - -interface _IAnimal { - name: string; -} -``` - -The following patterns are not warnings: - -```ts -interface IAnimal { - name: string; -} - -interface IIguana { - name: string; -} -``` - -### always and allowing underscores - -**Configuration:** `{ "prefixWithI": "always", "allowUnderscorePrefix": true }` - -The following patterns are considered warnings: - -```ts -interface Animal { - name: string; -} - -interface Iguana { - name: string; -} -``` - -The following patterns are not warnings: - -```ts -interface IAnimal { - name: string; -} - -interface IIguana { - name: string; -} - -interface _IAnimal { - name: string; -} -``` - -## When Not To Use It - -If you do not want to enforce interface name prefixing. - -## Further Reading - -TypeScript [Interfaces](https://www.typescriptlang.org/docs/handbook/interfaces.html) - -## Compatibility - -TSLint: [interface-name](https://palantir.github.io/tslint/rules/interface-name/) diff --git a/packages/eslint-plugin/docs/rules/member-naming.md b/packages/eslint-plugin/docs/rules/member-naming.md deleted file mode 100644 index 0dd8a5a2f29c..000000000000 --- a/packages/eslint-plugin/docs/rules/member-naming.md +++ /dev/null @@ -1,46 +0,0 @@ -# Enforces naming conventions for class members by visibility (`member-naming`) - -It can be helpful to enforce naming conventions for `private` (and sometimes `protected`) members of an object. For example, prefixing private properties with a `_` allows them to be easily discerned when being inspected by tools that do not have knowledge of TypeScript (such as most debuggers). - -## DEPRECATED - -This rule has been deprecated in favour of the [`naming-convention`](./naming-convention.md) rule. -It will be removed in a future version of this plugin. - -## Rule Details - -This rule allows you to enforce conventions for class property and method names by their visibility. By default, it enforces nothing. - -> Note: constructors are explicitly ignored regardless of the the regular expression options provided - -## Options - -You can specify a regular expression to test the names of properties for each visibility level: `public`, `protected`, `private`. - -Examples of **correct** code with `{ "private": "^_" }` specified: - -```ts -class HappyClass { - private _foo: string; - private _bar = 123; - private _fizz() {} -} -``` - -Examples of **incorrect** code with `{ "private": "^_" }` specified: - -```ts -class SadClass { - private foo: string; - private bar = 123; - private fizz() {} -} -``` - -## When Not To Use It - -If you do not want to enforce per-visibility naming rules for member properties. - -## Further Reading - -- ESLint's [`camelcase` rule](https://eslint.org/docs/rules/camelcase) diff --git a/packages/eslint-plugin/docs/rules/no-untyped-public-signature.md b/packages/eslint-plugin/docs/rules/no-untyped-public-signature.md deleted file mode 100644 index ffcd083b57dc..000000000000 --- a/packages/eslint-plugin/docs/rules/no-untyped-public-signature.md +++ /dev/null @@ -1,65 +0,0 @@ -# Disallow untyped public methods (`no-untyped-public-signature`) - -public methods are meant to be used by code outside of your class. By typing both the parameters and the return type of public methods they will be more readable and easy to use. - -## DEPRECATED - -This rule has been deprecated in favour of the [`explicit-module-boundary-types`](./explicit-module-boundary-types.md) rule. -It will be removed in a future version of this plugin. - -## Rule Details - -This rule aims to ensure that only typed public methods are declared in the code. - -The following patterns are considered warnings: - -```ts -// untyped parameter -public foo(param1): void { -} - -// untyped parameter -public foo(param1: any): void { -} - -// untyped return type -public foo(param1: string) { -} - -// untyped return type -public foo(param1: string): any { -} -``` - -The following patterns are not warnings: - -```ts -// typed public method -public foo(param1: string): void { -} - -// untyped private method -private foo(param1) { -} -``` - -## Options - -This rule, in its default state, does not require any argument. - -### `ignoredMethods` - -You may pass method names you would like this rule to ignore, like so: - -```jsonc -{ - "@typescript-eslint/no-untyped-public-signature": [ - "error", - { "ignoredMethods": ["ignoredMethodName"] } - ] -} -``` - -## When Not To Use It - -If you don't wish to type public methods. diff --git a/packages/eslint-plugin/src/rules/ban-ts-ignore.ts b/packages/eslint-plugin/src/rules/ban-ts-ignore.ts deleted file mode 100644 index bbeadfe5269d..000000000000 --- a/packages/eslint-plugin/src/rules/ban-ts-ignore.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { AST_TOKEN_TYPES } from '@typescript-eslint/experimental-utils'; -import * as util from '../util'; - -export default util.createRule({ - name: 'ban-ts-ignore', - meta: { - type: 'problem', - docs: { - description: 'Bans “// @ts-ignore” comments from being used', - category: 'Best Practices', - recommended: false, - }, - schema: [], - messages: { - tsIgnoreComment: - 'Do not use "// @ts-ignore" comments because they suppress compilation errors.', - }, - deprecated: true, - replacedBy: ['ban-ts-comment'], - }, - defaultOptions: [], - create(context) { - const tsIgnoreRegExp = /^\/*\s*@ts-ignore/; - const sourceCode = context.getSourceCode(); - - return { - Program(): void { - const comments = sourceCode.getAllComments(); - - comments.forEach(comment => { - if (comment.type !== AST_TOKEN_TYPES.Line) { - return; - } - if (tsIgnoreRegExp.test(comment.value)) { - context.report({ - node: comment, - messageId: 'tsIgnoreComment', - }); - } - }); - }, - }; - }, -}); diff --git a/packages/eslint-plugin/src/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts deleted file mode 100644 index 7d8c179f2b9d..000000000000 --- a/packages/eslint-plugin/src/rules/camelcase.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { - TSESTree, - AST_NODE_TYPES, -} from '@typescript-eslint/experimental-utils'; -import baseRule from 'eslint/lib/rules/camelcase'; -import * as util from '../util'; - -type Options = util.InferOptionsTypeFromRule; -type MessageIds = util.InferMessageIdsTypeFromRule; - -const schema = util.deepMerge( - Array.isArray(baseRule.meta.schema) - ? baseRule.meta.schema[0] - : baseRule.meta.schema, - { - properties: { - genericType: { - enum: ['always', 'never'], - }, - }, - }, -); - -export default util.createRule({ - name: 'camelcase', - meta: { - type: 'suggestion', - docs: { - description: 'Enforce camelCase naming convention', - category: 'Stylistic Issues', - recommended: false, - extendsBaseRule: true, - }, - deprecated: true, - replacedBy: ['naming-convention'], - schema: [schema], - messages: baseRule.meta.messages, - }, - defaultOptions: [ - { - allow: ['^UNSAFE_'], - ignoreDestructuring: false, - properties: 'never', - genericType: 'never', - }, - ], - create(context, [options]) { - const rules = baseRule.create(context); - const TS_PROPERTY_TYPES = [ - AST_NODE_TYPES.TSPropertySignature, - AST_NODE_TYPES.ClassProperty, - AST_NODE_TYPES.TSParameterProperty, - AST_NODE_TYPES.TSAbstractClassProperty, - ]; - - const genericType = options.genericType; - const properties = options.properties; - const allow = - options.allow?.map(entry => ({ - name: entry, - regex: new RegExp(entry), - })) ?? []; - - /** - * Checks if a string contains an underscore and isn't all upper-case - * @param name The string to check. - */ - function isUnderscored(name: string): boolean { - // if there's an underscore, it might be A_CONSTANT, which is okay - return name.includes('_') && name !== name.toUpperCase(); - } - - /** - * Checks if a string match the ignore list - * @param name The string to check. - * @returns if the string is ignored - * @private - */ - function isAllowed(name: string): boolean { - return ( - allow.findIndex( - entry => name === entry.name || entry.regex.test(name), - ) !== -1 - ); - } - - /** - * Checks if the the node is a valid TypeScript property type. - * @param node the node to be validated. - * @returns true if the node is a TypeScript property type. - * @private - */ - function isTSPropertyType(node: TSESTree.Node): boolean { - if (TS_PROPERTY_TYPES.includes(node.type)) { - return true; - } - - if (node.type === AST_NODE_TYPES.AssignmentPattern) { - return ( - node.parent !== undefined && - TS_PROPERTY_TYPES.includes(node.parent.type) - ); - } - - return false; - } - - function report(node: TSESTree.Identifier): void { - context.report({ - node, - messageId: 'notCamelCase', - data: { name: node.name }, - }); - } - - return { - Identifier(node): void { - /* - * Leading and trailing underscores are commonly used to flag - * private/protected identifiers, strip them - */ - const name = node.name.replace(/^_+|_+$/g, ''); - - // First, we ignore the node if it match the ignore list - if (isAllowed(name)) { - return; - } - - // Check TypeScript specific nodes - const parent = node.parent; - if (parent && isTSPropertyType(parent)) { - if (properties === 'always' && isUnderscored(name)) { - report(node); - } - - return; - } - - if (parent && parent.type === AST_NODE_TYPES.TSTypeParameter) { - if (genericType === 'always' && isUnderscored(name)) { - report(node); - } - - return; - } - - if (parent && parent.type === AST_NODE_TYPES.OptionalMemberExpression) { - // Report underscored object names - if ( - properties === 'always' && - parent.object.type === AST_NODE_TYPES.Identifier && - parent.object.name === node.name && - isUnderscored(name) - ) { - report(node); - } - - return; - } - - // Let the base rule deal with the rest - rules.Identifier(node); - }, - }; - }, -}); diff --git a/packages/eslint-plugin/src/rules/class-name-casing.ts b/packages/eslint-plugin/src/rules/class-name-casing.ts deleted file mode 100644 index 5871f47db92b..000000000000 --- a/packages/eslint-plugin/src/rules/class-name-casing.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { - TSESTree, - AST_NODE_TYPES, -} from '@typescript-eslint/experimental-utils'; -import * as util from '../util'; - -type Options = [ - { - allowUnderscorePrefix?: boolean; - }, -]; -type MessageIds = 'notPascalCased'; - -export default util.createRule({ - name: 'class-name-casing', - meta: { - type: 'suggestion', - docs: { - description: 'Require PascalCased class and interface names', - category: 'Best Practices', - recommended: false, - }, - deprecated: true, - replacedBy: ['naming-convention'], - messages: { - notPascalCased: "{{friendlyName}} '{{name}}' must be PascalCased.", - }, - schema: [ - { - type: 'object', - properties: { - allowUnderscorePrefix: { - type: 'boolean', - default: false, - }, - }, - additionalProperties: false, - }, - ], - }, - defaultOptions: [{ allowUnderscorePrefix: false }], - create(context, [options]) { - const UNDERSCORE = '_'; - - /** - * Determine if the string is Upper cased - * @param str - */ - function isUpperCase(str: string): boolean { - return str === str.toUpperCase(); - } - - /** - * Determine if the identifier name is PascalCased - * @param name The identifier name - */ - function isPascalCase(name: string): boolean { - const startIndex = - options.allowUnderscorePrefix && name.startsWith(UNDERSCORE) ? 1 : 0; - - return ( - isUpperCase(name.charAt(startIndex)) && - !name.includes(UNDERSCORE, startIndex) - ); - } - - /** - * Report a class declaration as invalid - * @param decl The declaration - * @param id The name of the declaration - */ - function report( - decl: - | TSESTree.ClassDeclaration - | TSESTree.TSInterfaceDeclaration - | TSESTree.ClassExpression, - id: TSESTree.Identifier, - ): void { - let friendlyName; - - switch (decl.type) { - case AST_NODE_TYPES.ClassDeclaration: - case AST_NODE_TYPES.ClassExpression: - friendlyName = decl.abstract ? 'Abstract class' : 'Class'; - break; - case AST_NODE_TYPES.TSInterfaceDeclaration: - friendlyName = 'Interface'; - break; - } - - context.report({ - node: id, - messageId: 'notPascalCased', - data: { - friendlyName, - name: id.name, - }, - }); - } - - return { - 'ClassDeclaration, TSInterfaceDeclaration, ClassExpression'( - node: - | TSESTree.ClassDeclaration - | TSESTree.TSInterfaceDeclaration - | TSESTree.ClassExpression, - ): void { - // class expressions (i.e. export default class {}) are OK - if (node.id && !isPascalCase(node.id.name)) { - report(node, node.id); - } - }, - "VariableDeclarator[init.type='ClassExpression']"( - node: TSESTree.VariableDeclarator, - ): void { - if ( - node.id.type === AST_NODE_TYPES.ArrayPattern || - node.id.type === AST_NODE_TYPES.ObjectPattern - ) { - // TODO - handle the BindingPattern case maybe? - /* - // this example makes me barf, but it's valid code - var { bar } = class { - static bar() { return 2 } - } - */ - } else { - const id = node.id; - const nodeInit = node.init as TSESTree.ClassExpression; - - if (id && !nodeInit.id && !isPascalCase(id.name)) { - report(nodeInit, id); - } - } - }, - }; - }, -}); diff --git a/packages/eslint-plugin/src/rules/generic-type-naming.ts b/packages/eslint-plugin/src/rules/generic-type-naming.ts deleted file mode 100644 index 14a697f2e604..000000000000 --- a/packages/eslint-plugin/src/rules/generic-type-naming.ts +++ /dev/null @@ -1,52 +0,0 @@ -import * as util from '../util'; - -type Options = [string?]; -type MessageIds = 'paramNotMatchRule'; - -export default util.createRule({ - name: 'generic-type-naming', - meta: { - type: 'suggestion', - docs: { - description: 'Enforces naming of generic type variables', - category: 'Stylistic Issues', - // too opinionated to be recommended - recommended: false, - }, - deprecated: true, - replacedBy: ['naming-convention'], - messages: { - paramNotMatchRule: - 'Type parameter {{name}} does not match rule {{rule}}.', - }, - schema: [ - { - type: 'string', - }, - ], - }, - defaultOptions: [ - // Matches: T , TA , TAbc , TA1Bca , T1 , T2 - '^T([A-Z0-9][a-zA-Z0-9]*){0,1}$', - ], - create(context, [rule]) { - const regex = new RegExp(rule!); - - return { - TSTypeParameter(node): void { - const name = node.name.name; - - if (name && !regex.test(name)) { - context.report({ - node, - messageId: 'paramNotMatchRule', - data: { - name, - rule, - }, - }); - } - }, - }; - }, -}); diff --git a/packages/eslint-plugin/src/rules/index.ts b/packages/eslint-plugin/src/rules/index.ts index 9c1c26444d74..913a72ef159b 100644 --- a/packages/eslint-plugin/src/rules/index.ts +++ b/packages/eslint-plugin/src/rules/index.ts @@ -2,11 +2,8 @@ import adjacentOverloadSignatures from './adjacent-overload-signatures'; import arrayType from './array-type'; import awaitThenable from './await-thenable'; import banTsComment from './ban-ts-comment'; -import banTsIgnore from './ban-ts-ignore'; import banTypes from './ban-types'; import braceStyle from './brace-style'; -import camelcase from './camelcase'; -import classNameCasing from './class-name-casing'; import classLiteralPropertyStyle from './class-literal-property-style'; import commaSpacing from './comma-spacing'; import consistentTypeAssertions from './consistent-type-assertions'; @@ -17,12 +14,9 @@ import explicitFunctionReturnType from './explicit-function-return-type'; import explicitMemberAccessibility from './explicit-member-accessibility'; import explicitModuleBoundaryTypes from './explicit-module-boundary-types'; import funcCallSpacing from './func-call-spacing'; -import genericTypeNaming from './generic-type-naming'; import indent from './indent'; -import interfaceNamePrefix from './interface-name-prefix'; import keywordSpacing from './keyword-spacing'; import memberDelimiterStyle from './member-delimiter-style'; -import memberNaming from './member-naming'; import memberOrdering from './member-ordering'; import methodSignatureStyle from './method-signature-style'; import namingConvention from './naming-convention'; @@ -63,7 +57,6 @@ import noUnsafeAssignment from './no-unsafe-assignment'; import noUnsafeCall from './no-unsafe-call'; import noUnsafeMemberAccess from './no-unsafe-member-access'; import noUnsafeReturn from './no-unsafe-return'; -import noUntypedPublicSignature from './no-untyped-public-signature'; import noUnusedExpressions from './no-unused-expressions'; import noUnusedVars from './no-unused-vars'; import noUnusedVarsExperimental from './no-unused-vars-experimental'; @@ -106,11 +99,8 @@ export default { 'array-type': arrayType, 'await-thenable': awaitThenable, 'ban-ts-comment': banTsComment, - 'ban-ts-ignore': banTsIgnore, 'ban-types': banTypes, 'brace-style': braceStyle, - camelcase: camelcase, - 'class-name-casing': classNameCasing, 'class-literal-property-style': classLiteralPropertyStyle, 'comma-spacing': commaSpacing, 'consistent-type-assertions': consistentTypeAssertions, @@ -121,13 +111,10 @@ export default { 'explicit-member-accessibility': explicitMemberAccessibility, 'explicit-module-boundary-types': explicitModuleBoundaryTypes, 'func-call-spacing': funcCallSpacing, - 'generic-type-naming': genericTypeNaming, indent: indent, 'init-declarations': initDeclarations, - 'interface-name-prefix': interfaceNamePrefix, 'keyword-spacing': keywordSpacing, 'member-delimiter-style': memberDelimiterStyle, - 'member-naming': memberNaming, 'member-ordering': memberOrdering, 'method-signature-style': methodSignatureStyle, 'naming-convention': namingConvention, @@ -168,7 +155,6 @@ export default { 'no-unsafe-call': noUnsafeCall, 'no-unsafe-member-access': noUnsafeMemberAccess, 'no-unsafe-return': noUnsafeReturn, - 'no-untyped-public-signature': noUntypedPublicSignature, 'no-unused-expressions': noUnusedExpressions, 'no-unused-vars-experimental': noUnusedVarsExperimental, 'no-unused-vars': noUnusedVars, diff --git a/packages/eslint-plugin/src/rules/interface-name-prefix.ts b/packages/eslint-plugin/src/rules/interface-name-prefix.ts deleted file mode 100644 index 281a9eb61978..000000000000 --- a/packages/eslint-plugin/src/rules/interface-name-prefix.ts +++ /dev/null @@ -1,144 +0,0 @@ -import * as util from '../util'; - -type ParsedOptions = - | { - prefixWithI: 'never'; - } - | { - prefixWithI: 'always'; - allowUnderscorePrefix: boolean; - }; -type Options = [ - | 'never' - | 'always' - | { - prefixWithI?: 'never'; - } - | { - prefixWithI: 'always'; - allowUnderscorePrefix?: boolean; - }, -]; -type MessageIds = 'noPrefix' | 'alwaysPrefix'; - -/** - * Parses a given value as options. - */ -export function parseOptions([options]: Options): ParsedOptions { - if (options === 'always') { - return { prefixWithI: 'always', allowUnderscorePrefix: false }; - } - if (options !== 'never' && options.prefixWithI === 'always') { - return { - prefixWithI: 'always', - allowUnderscorePrefix: !!options.allowUnderscorePrefix, - }; - } - return { prefixWithI: 'never' }; -} - -export default util.createRule({ - name: 'interface-name-prefix', - meta: { - type: 'suggestion', - docs: { - description: - 'Require that interface names should or should not prefixed with `I`', - category: 'Stylistic Issues', - recommended: false, - }, - deprecated: true, - replacedBy: ['naming-convention'], - messages: { - noPrefix: 'Interface name must not be prefixed with "I".', - alwaysPrefix: 'Interface name must be prefixed with "I".', - }, - schema: [ - { - oneOf: [ - { - enum: [ - // Deprecated, equivalent to: { prefixWithI: 'never' } - 'never', - // Deprecated, equivalent to: { prefixWithI: 'always', allowUnderscorePrefix: false } - 'always', - ], - }, - { - type: 'object', - properties: { - prefixWithI: { - type: 'string', - enum: ['never'], - }, - }, - additionalProperties: false, - }, - { - type: 'object', - properties: { - prefixWithI: { - type: 'string', - enum: ['always'], - }, - allowUnderscorePrefix: { - type: 'boolean', - }, - }, - required: ['prefixWithI'], // required to select this "oneOf" alternative - additionalProperties: false, - }, - ], - }, - ], - }, - defaultOptions: [{ prefixWithI: 'never' }], - create(context, [options]) { - const parsedOptions = parseOptions([options]); - - /** - * Checks if a string is prefixed with "I". - * @param name The string to check - */ - function isPrefixedWithI(name: string): boolean { - return /^I[A-Z]/.test(name); - } - - /** - * Checks if a string is prefixed with "I" or "_I". - * @param name The string to check - */ - function isPrefixedWithIOrUnderscoreI(name: string): boolean { - return /^_?I[A-Z]/.test(name); - } - - return { - TSInterfaceDeclaration(node): void { - if (parsedOptions.prefixWithI === 'never') { - if (isPrefixedWithIOrUnderscoreI(node.id.name)) { - context.report({ - node: node.id, - messageId: 'noPrefix', - }); - } - } else { - if (parsedOptions.allowUnderscorePrefix) { - if (!isPrefixedWithIOrUnderscoreI(node.id.name)) { - context.report({ - node: node.id, - messageId: 'alwaysPrefix', - }); - } - } else { - if (!isPrefixedWithI(node.id.name)) { - context.report({ - node: node.id, - messageId: 'alwaysPrefix', - }); - } - } - } - }, - }; - }, -}); diff --git a/packages/eslint-plugin/src/rules/member-naming.ts b/packages/eslint-plugin/src/rules/member-naming.ts deleted file mode 100644 index 4facce887e5f..000000000000 --- a/packages/eslint-plugin/src/rules/member-naming.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { - TSESTree, - AST_NODE_TYPES, -} from '@typescript-eslint/experimental-utils'; -import * as util from '../util'; - -interface Config { - private?: T; - protected?: T; - public?: T; -} -type Modifiers = keyof Config; -type Options = [Config]; -type MessageIds = 'incorrectName'; - -export default util.createRule({ - name: 'member-naming', - meta: { - type: 'suggestion', - docs: { - description: - 'Enforces naming conventions for class members by visibility', - category: 'Stylistic Issues', - recommended: false, - }, - deprecated: true, - replacedBy: ['naming-convention'], - messages: { - incorrectName: - '{{accessibility}} property {{name}} should match {{convention}}.', - }, - schema: [ - { - type: 'object', - properties: { - public: { - type: 'string', - minLength: 1, - format: 'regex', - }, - protected: { - type: 'string', - minLength: 1, - format: 'regex', - }, - private: { - type: 'string', - minLength: 1, - format: 'regex', - }, - }, - additionalProperties: false, - minProperties: 1, - }, - ], - }, - defaultOptions: [{}], - create(context, [config]) { - const sourceCode = context.getSourceCode(); - - const conventions = (Object.keys(config) as Modifiers[]).reduce< - Config - >((acc, accessibility) => { - acc[accessibility] = new RegExp(config[accessibility]!); - - return acc; - }, {}); - - function getParameterNode( - node: TSESTree.TSParameterProperty, - ): TSESTree.Identifier | null { - if (node.parameter.type === AST_NODE_TYPES.AssignmentPattern) { - return node.parameter.left as TSESTree.Identifier; - } - - if (node.parameter.type === AST_NODE_TYPES.Identifier) { - return node.parameter; - } - - return null; - } - - function validateParameterName(node: TSESTree.TSParameterProperty): void { - const parameterNode = getParameterNode(node); - if (!parameterNode) { - return; - } - - validate(parameterNode, parameterNode.name, node.accessibility); - } - - function validateName( - node: TSESTree.MethodDefinition | TSESTree.ClassProperty, - ): void { - if ( - node.type === AST_NODE_TYPES.MethodDefinition && - node.kind === 'constructor' - ) { - return; - } - - validate( - node.key, - util.getNameFromMember(node, sourceCode), - node.accessibility, - ); - } - - /** - * Check that the name matches the convention for its accessibility. - * @param {ASTNode} node the named node to evaluate. - * @param {string} name - * @param {Modifiers} accessibility - * @returns {void} - * @private - */ - function validate( - node: TSESTree.Identifier | TSESTree.Expression, - name: string, - accessibility: Modifiers = 'public', - ): void { - const convention = conventions[accessibility]; - if (!convention || convention.test(name)) { - return; - } - - context.report({ - node, - messageId: 'incorrectName', - data: { accessibility, name, convention }, - }); - } - - return { - TSParameterProperty: validateParameterName, - MethodDefinition: validateName, - ClassProperty: validateName, - }; - }, -}); diff --git a/packages/eslint-plugin/src/rules/no-base-to-string.ts b/packages/eslint-plugin/src/rules/no-base-to-string.ts index 364d7aa0194c..41cecb32c67b 100644 --- a/packages/eslint-plugin/src/rules/no-base-to-string.ts +++ b/packages/eslint-plugin/src/rules/no-base-to-string.ts @@ -14,8 +14,6 @@ enum Usefulness { type Options = [ { - /** @deprecated This option is now ignored and treated as always true, it will be removed in 3.0 */ - ignoreTaggedTemplateExpressions?: boolean; ignoredTypeNames?: string[]; }, ]; @@ -39,10 +37,6 @@ export default util.createRule({ { type: 'object', properties: { - ignoreTaggedTemplateExpressions: { - type: 'boolean', - default: true, - }, ignoredTypeNames: { type: 'array', items: { @@ -57,7 +51,6 @@ export default util.createRule({ }, defaultOptions: [ { - ignoreTaggedTemplateExpressions: true, ignoredTypeNames: ['RegExp'], }, ], diff --git a/packages/eslint-plugin/src/rules/no-untyped-public-signature.ts b/packages/eslint-plugin/src/rules/no-untyped-public-signature.ts deleted file mode 100644 index cff725facc9c..000000000000 --- a/packages/eslint-plugin/src/rules/no-untyped-public-signature.ts +++ /dev/null @@ -1,125 +0,0 @@ -import * as util from '../util'; -import { - AST_NODE_TYPES, - TSESTree, -} from '@typescript-eslint/experimental-utils'; - -type MessageIds = 'noReturnType' | 'untypedParameter'; - -type Options = [{ ignoredMethods: string[] }]; - -export default util.createRule({ - name: 'no-untyped-public-signature', - meta: { - deprecated: true, - replacedBy: ['explicit-module-boundary-types'], - docs: { - description: 'Disallow untyped public methods', - category: 'Best Practices', - recommended: false, - }, - messages: { - noReturnType: 'Public method has no return type.', - untypedParameter: 'Public method parameters should be typed.', - }, - schema: [ - { - allowAdditionalProperties: false, - properties: { - ignoredMethods: { - type: 'array', - items: { - type: 'string', - }, - }, - }, - type: 'object', - }, - ], - type: 'suggestion', - }, - defaultOptions: [{ ignoredMethods: [] }], - create(context, [options]) { - const ignoredMethods = new Set(options.ignoredMethods); - - function isPublicMethod( - node: TSESTree.MethodDefinition | TSESTree.TSAbstractMethodDefinition, - ): boolean { - return node.accessibility === 'public' || !node.accessibility; - } - - function isIgnoredMethod( - node: TSESTree.MethodDefinition | TSESTree.TSAbstractMethodDefinition, - ignoredMethods: Set, - ): boolean { - if ( - node.key.type === AST_NODE_TYPES.Literal && - typeof node.key.value === 'string' - ) { - return ignoredMethods.has(node.key.value); - } - if ( - node.key.type === AST_NODE_TYPES.TemplateLiteral && - node.key.expressions.length === 0 - ) { - return ignoredMethods.has(node.key.quasis[0].value.raw); - } - if (!node.computed && node.key.type === AST_NODE_TYPES.Identifier) { - return ignoredMethods.has(node.key.name); - } - - return false; - } - - function isParamTyped(node: TSESTree.Identifier): boolean { - return ( - !!node.typeAnnotation && - node.typeAnnotation.typeAnnotation.type !== AST_NODE_TYPES.TSAnyKeyword - ); - } - - function isReturnTyped( - node: TSESTree.TSTypeAnnotation | undefined, - ): boolean { - if (!node) { - return false; - } - return ( - node.typeAnnotation && - node.typeAnnotation.type !== AST_NODE_TYPES.TSAnyKeyword - ); - } - - return { - 'TSAbstractMethodDefinition, MethodDefinition'( - node: TSESTree.MethodDefinition | TSESTree.TSAbstractMethodDefinition, - ): void { - if (isPublicMethod(node) && !isIgnoredMethod(node, ignoredMethods)) { - const paramIdentifiers = node.value.params.filter( - param => param.type === AST_NODE_TYPES.Identifier, - ) as TSESTree.Identifier[]; - const identifiersHaveTypes = paramIdentifiers.every(isParamTyped); - if (!identifiersHaveTypes) { - context.report({ - node, - messageId: 'untypedParameter', - data: {}, - }); - } - - if ( - node.kind !== 'constructor' && - node.kind !== 'set' && - !isReturnTyped(node.value.returnType) - ) { - context.report({ - node, - messageId: 'noReturnType', - data: {}, - }); - } - } - }, - }; - }, -});