Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(eslint-plugin): add no-unused-vars-experimental #688

Merged
merged 4 commits into from Nov 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/eslint-plugin/README.md
Expand Up @@ -186,6 +186,7 @@ Then you should add `airbnb` (or `airbnb-base`) to your `extends` section of `.e
| [`@typescript-eslint/no-untyped-public-signature`](./docs/rules/no-untyped-public-signature.md) | Requires that all public method arguments and return type will be explicitly typed | | | |
| [`@typescript-eslint/no-unused-expressions`](./docs/rules/no-unused-expressions.md) | Disallow unused expressions | | | |
| [`@typescript-eslint/no-unused-vars`](./docs/rules/no-unused-vars.md) | Disallow unused variables | :heavy_check_mark: | | |
| [`@typescript-eslint/no-unused-vars-experimental`](./docs/rules/no-unused-vars-experimental.md) | Disallow unused variables and arguments. | | | :thought_balloon: |
| [`@typescript-eslint/no-use-before-define`](./docs/rules/no-use-before-define.md) | Disallow the use of variables before they are defined | :heavy_check_mark: | | |
| [`@typescript-eslint/no-useless-constructor`](./docs/rules/no-useless-constructor.md) | Disallow unnecessary constructors | | | |
| [`@typescript-eslint/no-var-requires`](./docs/rules/no-var-requires.md) | Disallows the use of require statements except in import statements | :heavy_check_mark: | | |
Expand Down
115 changes: 115 additions & 0 deletions packages/eslint-plugin/docs/rules/no-unused-vars-experimental.md
@@ -0,0 +1,115 @@
# Disallow unused variables and arguments (no-unused-vars-experimental)

Variables that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such variables take up space in the code and can lead to confusion by readers.

## Rule Details

This rule leverages the TypeScript compiler's unused variable checks to report. This means that with all rule options set to `false`, it should report the same errors as if you used both the `noUnusedLocals` and `noUnusedParameters` compiler options.

This rule is vastly different to, and maintains no compatability with the base eslint version of the rule.

### Limitations

There are two limitations to this rule when compared with eslint's `no-unused-vars` rule, which are imposed by the fact that it directly uses TypeScript's implementation.

1. This rule only works on files that TypeScript deems is a module (i.e. it has an `import` or an `export` statement).
2. The rule is significantly less configurable, as it cannot deviate too far from the base implementation.

## Supported Nodes

This rule supports checks on the following features:

- Declarations:
- `var` / `const` / `let`
- `function`
- `class`
- `enum`
- `interface`
- `type`
- Class methods
- Class properties and parameter properties
- Function parameters
- Generic type parameters
- Import statements

## Options

```ts
type Options = {
ignoredNamesRegex?: string | boolean;
ignoreArgsIfArgsAfterAreUsed?: boolean;
};

const defaultOptions: Options = {
ignoredNamesRegex: '^_',
ignoreArgsIfArgsAfterAreUsed: false,
};
```

### ignoredNamesRegex

This option accepts a regex string to match names against.
Any matched names will be ignored and have no errors reported.
If you set it to false, it will never ignore any names.

The default value is `'^_'` (i.e. matches any name prefixed with an underscore).

Examples of valid code with `{ variables: { ignoredNamesRegex: '^_' } }`.

```ts
const _unusedVar = 'unused';
class _Unused {
private _unused = 1;
private _unusedMethod() {}
}
function _unusedFunction() {}
enum _UnusedEnum {
a = 1,
}
interface _UnusedInterface {}
type _UnusedType = {};
```

**_NOTE:_** The TypeScript compiler automatically ignores imports, function arguments, type parameter declarations, and object destructuring variables prefixed with an underscore.
As this is hard-coded into the compiler, we cannot change this.

Examples of valid code based on the unchangable compiler settings

```ts
import _UnusedDefault, { _UnusedNamed } from 'foo';
export function foo(_unusedProp: string) {}
export class Foo<_UnusedGeneric> {}
const { prop: _unusedDesctructure } = foo;
```

## ignoreArgsIfArgsAfterAreUsed

When true, this option will ignore unused function arguments if the arguments proceeding arguments are used.

Examples of invalid code with `{ ignoreArgsIfArgsAfterAreUsed: false }`

```ts
function foo(unused: string, used: number) {
console.log(used);
}

class Foo {
constructor(unused: string, public used: number) {
console.log(used);
}
}
```

Examples of valid code with `{ ignoreArgsIfArgsAfterAreUsed: true }`

```ts
function foo(unused: string, used: number) {
console.log(used);
}

class Foo {
constructor(unused: string, public used: number) {
console.log(used);
}
}
```
3 changes: 2 additions & 1 deletion packages/eslint-plugin/src/configs/all.json
Expand Up @@ -31,8 +31,8 @@
"@typescript-eslint/no-empty-function": "error",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-explicit-any": "error",
"no-extra-parens": "off",
"@typescript-eslint/no-extra-non-null-assertion": "error",
"no-extra-parens": "off",
"@typescript-eslint/no-extra-parens": "error",
"@typescript-eslint/no-extraneous-class": "error",
"@typescript-eslint/no-floating-promises": "error",
Expand All @@ -57,6 +57,7 @@
"@typescript-eslint/no-unused-expressions": "error",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-unused-vars-experimental": "error",
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": "error",
"no-useless-constructor": "off",
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-plugin/src/rules/index.ts
Expand Up @@ -41,6 +41,7 @@ import noUnnecessaryCondition from './no-unnecessary-condition';
import noUnnecessaryQualifier from './no-unnecessary-qualifier';
import noUnnecessaryTypeAssertion from './no-unnecessary-type-assertion';
import noUnusedVars from './no-unused-vars';
import noUnusedVarsExperimental from './no-unused-vars-experimental';
import noUntypedPublicSignature from './no-untyped-public-signature';
import noUnusedExpressions from './no-unused-expressions';
import noUseBeforeDefine from './no-use-before-define';
Expand Down Expand Up @@ -116,6 +117,7 @@ export default {
'no-unnecessary-type-assertion': noUnnecessaryTypeAssertion,
'no-untyped-public-signature': noUntypedPublicSignature,
'no-unused-vars': noUnusedVars,
'no-unused-vars-experimental': noUnusedVarsExperimental,
'no-unused-expressions': noUnusedExpressions,
'no-use-before-define': noUseBeforeDefine,
'no-useless-constructor': noUselessConstructor,
Expand Down