Skip to content

Commit

Permalink
feat(eslint-plugin): create ban-ts-comment rule (#1361)
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Rath authored and bradzacher committed Jan 21, 2020
1 parent 0b5f6f5 commit 2a83d13
Show file tree
Hide file tree
Showing 9 changed files with 389 additions and 2 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Expand Up @@ -61,6 +61,7 @@
"estree",
"linebreaks",
"necroing",
"nocheck",
"nullish",
"parameterised",
"performant",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/README.md
Expand Up @@ -98,7 +98,7 @@ Pro Tip: For larger codebases you may want to consider splitting our linting int
| [`@typescript-eslint/adjacent-overload-signatures`](./docs/rules/adjacent-overload-signatures.md) | Require that member overloads be consecutive | :heavy_check_mark: | | |
| [`@typescript-eslint/array-type`](./docs/rules/array-type.md) | Requires using either `T[]` or `Array<T>` for arrays | | :wrench: | |
| [`@typescript-eslint/await-thenable`](./docs/rules/await-thenable.md) | Disallows awaiting a value that is not a Thenable | :heavy_check_mark: | | :thought_balloon: |
| [`@typescript-eslint/ban-ts-ignore`](./docs/rules/ban-ts-ignore.md) | Bans // @ts-ignore comments from being used | :heavy_check_mark: | | |
| [`@typescript-eslint/ban-ts-comment`](./docs/rules/ban-ts-comment.md) | Bans `// @ts-<directive>` comments from being used | | | |
| [`@typescript-eslint/ban-types`](./docs/rules/ban-types.md) | Bans specific types from being used | :heavy_check_mark: | :wrench: | |
| [`@typescript-eslint/consistent-type-assertions`](./docs/rules/consistent-type-assertions.md) | Enforces consistent usage of type assertions | :heavy_check_mark: | | |
| [`@typescript-eslint/consistent-type-definitions`](./docs/rules/consistent-type-definitions.md) | Consistent with type definition either `interface` or `type` | | :wrench: | |
Expand Down
65 changes: 65 additions & 0 deletions packages/eslint-plugin/docs/rules/ban-ts-comment.md
@@ -0,0 +1,65 @@
# Bans `// @ts-<directive>` comments from being used (`ban-ts-comment`)

TypeScript provides several directive comments that can be used to alter how it processes files.
Using these to suppress TypeScript Compiler Errors reduces the effectiveness of TypeScript overall.

The directive comments supported by TypeScript are:

```
// @ts-ignore
// @ts-nocheck
// @ts-check
```

## Rule Details

This rule lets you set which directive comments you want to allow in your codebase.
By default, only `@ts-check` is allowed, as it enables rather then suppresses errors.

The configuration looks like this:

```
interface Options {
'ts-ignore'?: boolean;
'ts-nocheck'?: boolean;
'ts-check'?: boolean;
}
const defaultOptions: Options = {
'ts-ignore': true,
'ts-nocheck': true,
'ts-check': false
}
```

A value of `true` for a particular directive means that this rule will report if it finds any usage of said directive.

For example, with the defaults above 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 want to use all of the TypeScript directives.

## 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/)
2 changes: 2 additions & 0 deletions packages/eslint-plugin/docs/rules/ban-ts-ignore.md
@@ -1,5 +1,7 @@
# 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.

## Rule Details
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/configs/all.json
Expand Up @@ -4,7 +4,7 @@
"@typescript-eslint/adjacent-overload-signatures": "error",
"@typescript-eslint/array-type": "error",
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/ban-ts-ignore": "error",
"@typescript-eslint/ban-ts-comment": "error",
"@typescript-eslint/ban-types": "error",
"brace-style": "off",
"@typescript-eslint/brace-style": "error",
Expand Down
82 changes: 82 additions & 0 deletions packages/eslint-plugin/src/rules/ban-ts-comment.ts
@@ -0,0 +1,82 @@
import * as util from '../util';

interface Options {
'ts-ignore'?: boolean;
'ts-nocheck'?: boolean;
'ts-check'?: boolean;
}

const defaultOptions: [Options] = [
{
'ts-ignore': true,
'ts-nocheck': true,
'ts-check': false,
},
];

type MessageIds = 'tsDirectiveComment';

export default util.createRule<[Options], MessageIds>({
name: 'ban-ts-comment',
meta: {
type: 'problem',
docs: {
description: 'Bans `// @ts-<directive>` comments from being used',
category: 'Best Practices',
recommended: false,
},
messages: {
tsDirectiveComment:
'Do not use "// @ts-{directive}" because it alters compilation errors.',
},
schema: [
{
type: 'object',
properties: {
'ts-ignore': {
type: 'boolean',
default: true,
},
'ts-nocheck': {
type: 'boolean',
default: true,
},
'ts-check': {
type: 'boolean',
default: false,
},
},
additionalProperties: false,
},
],
},
defaultOptions,
create(context, [options]) {
const tsCommentRegExp = /^\/*\s*@ts-(ignore|check|nocheck)/;
const sourceCode = context.getSourceCode();

return {
Program(): void {
const comments = sourceCode.getAllComments();

comments.forEach(comment => {
if (comment.type !== 'Line') {
return;
}

const [, directive] = tsCommentRegExp.exec(comment.value) ?? [];

const fullDirective = `ts-${directive}` as keyof Options;

if (options[fullDirective]) {
context.report({
data: { directive },
node: comment,
messageId: 'tsDirectiveComment',
});
}
});
},
};
},
});
2 changes: 2 additions & 0 deletions packages/eslint-plugin/src/rules/ban-ts-ignore.ts
Expand Up @@ -14,6 +14,8 @@ export default util.createRule({
tsIgnoreComment:
'Do not use "// @ts-ignore" comments because they suppress compilation errors.',
},
deprecated: true,
replacedBy: ['@typescript-eslint/ban-ts-comment'],
},
defaultOptions: [],
create(context) {
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-plugin/src/rules/index.ts
Expand Up @@ -2,6 +2,7 @@ import adjacentOverloadSignatures from './adjacent-overload-signatures';
import arrayType from './array-type';
import awaitThenable from './await-thenable';
import banTsIgnore from './ban-ts-ignore';
import banTsComment from './ban-ts-comment';
import banTypes from './ban-types';
import braceStyle from './brace-style';
import camelcase from './camelcase';
Expand Down Expand Up @@ -85,6 +86,7 @@ export default {
'array-type': arrayType,
'await-thenable': awaitThenable,
'ban-ts-ignore': banTsIgnore,
'ban-ts-comment': banTsComment,
'ban-types': banTypes,
'brace-style': braceStyle,
camelcase: camelcase,
Expand Down

0 comments on commit 2a83d13

Please sign in to comment.