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

fix(eslint-plugin): no-explicit-any constructor functions (& more) not ignored by ignoreRestArgs property #1711

Merged
merged 15 commits into from Apr 3, 2020
Merged
76 changes: 31 additions & 45 deletions packages/eslint-plugin/docs/rules/no-explicit-any.md
Expand Up @@ -119,30 +119,23 @@ function foo2(...args: readonly any[]): void {}
function foo3(...args: Array<any>): void {}
function foo4(...args: ReadonlyArray<any>): void {}

const bar1 = (...args: any[]): void {}
const bar2 = (...args: readonly any[]): void {}
const bar3 = (...args: Array<any>): void {}
const bar4 = (...args: ReadonlyArray<any>): void {}
declare function bar(...args: any[]): void;

const baz1 = function (...args: any[]) {}
const baz2 = function (...args: readonly any[]) {}
const baz3 = function (...args: Array<any>) {}
const baz4 = function (...args: ReadonlyArray<any>) {}
const baz = (...args: any[]) => {};
const qux = function(...args: any[]) {};

interface Qux1 { (...args: any[]): void; }
interface Qux2 { (...args: readonly any[]): void; }
interface Qux3 { (...args: Array<any>): void; }
interface Qux4 { (...args: ReadonlyArray<any>): void; }
type Quux = (...args: any[]) => void;
type Quuz = new (...args: any[]) => void;

function quux1(fn: (...args: any[]) => void): void {}
function quux2(fn: (...args: readonly any[]) => void): void {}
function quux3(fn: (...args: Array<any>) => void): void {}
function quux4(fn: (...args: ReadonlyArray<any>) => void): void {}

function quuz1(): ((...args: any[]) => void) {}
function quuz2(): ((...args: readonly any[]) => void) {}
function quuz3(): ((...args: Array<any>) => void) {}
function quuz4(): ((...args: ReadonlyArray<any>) => void) {}
interface Grault {
(...args: any[]): void;
}
interface Corge {
new (...args: any[]): void;
}
interface Garply {
f(...args: any[]): void;
}
```

Examples of **correct** code for the `{ "ignoreRestArgs": true }` option:
Expand All @@ -155,30 +148,23 @@ function foo2(...args: readonly any[]): void {}
function foo3(...args: Array<any>): void {}
function foo4(...args: ReadonlyArray<any>): void {}

const bar1 = (...args: any[]): void {}
const bar2 = (...args: readonly any[]): void {}
const bar3 = (...args: Array<any>): void {}
const bar4 = (...args: ReadonlyArray<any>): void {}

const baz1 = function (...args: any[]) {}
const baz2 = function (...args: readonly any[]) {}
const baz3 = function (...args: Array<any>) {}
const baz4 = function (...args: ReadonlyArray<any>) {}

interface Qux1 { (...args: any[]): void; }
interface Qux2 { (...args: readonly any[]): void; }
interface Qux3 { (...args: Array<any>): void; }
interface Qux4 { (...args: ReadonlyArray<any>): void; }

function quux1(fn: (...args: any[]) => void): void {}
function quux2(fn: (...args: readonly any[]) => void): void {}
function quux3(fn: (...args: Array<any>) => void): void {}
function quux4(fn: (...args: ReadonlyArray<any>) => void): void {}

function quuz1(): ((...args: any[]) => void) {}
function quuz2(): ((...args: readonly any[]) => void) {}
function quuz3(): ((...args: Array<any>) => void) {}
function quuz4(): ((...args: ReadonlyArray<any>) => void) {}
declare function bar(...args: any[]): void;

const baz = (...args: any[]) => {};
const qux = function(...args: any[]) {};

type Quux = (...args: any[]) => void;
type Quuz = new (...args: any[]) => void;

interface Grault {
(...args: any[]): void;
}
interface Corge {
new (...args: any[]): void;
}
interface Garply {
f(...args: any[]): void;
}
```

## When Not To Use It
Expand Down
19 changes: 12 additions & 7 deletions packages/eslint-plugin/src/rules/no-explicit-any.ts
Expand Up @@ -53,18 +53,23 @@ export default util.createRule<Options, MessageIds>({
],
create(context, [{ ignoreRestArgs, fixToUnknown }]) {
/**
* Checks if the node is an arrow function, function declaration or function expression
* Checks if the node is an arrow function, function/constructor declaration or function expression
* @param node the node to be validated.
* @returns true if the node is an arrow function, function declaration, function expression, function type, or call signature
* @returns true if the node is any kind of function declaration or expression
* @private
*/
function isNodeValidFunction(node: TSESTree.Node): boolean {
return [
AST_NODE_TYPES.ArrowFunctionExpression,
AST_NODE_TYPES.FunctionDeclaration,
AST_NODE_TYPES.FunctionExpression,
AST_NODE_TYPES.TSFunctionType,
AST_NODE_TYPES.TSCallSignatureDeclaration,
AST_NODE_TYPES.ArrowFunctionExpression, // const x = (...args: any[]) => {};
AST_NODE_TYPES.FunctionDeclaration, // function f(...args: any[]) {}
AST_NODE_TYPES.FunctionExpression, // const x = function(...args: any[]) {};
AST_NODE_TYPES.TSEmptyBodyFunctionExpression, // declare class A { f(...args: any[]): unknown; }
AST_NODE_TYPES.TSFunctionType, // type T = (...args: any[]) => unknown;
AST_NODE_TYPES.TSConstructorType, // type T = new (...args: any[]) => unknown
AST_NODE_TYPES.TSCallSignatureDeclaration, // type T = {(...args: any[]): unknown};
AST_NODE_TYPES.TSConstructSignatureDeclaration, // type T = {new (...args: any[]): unknown};
AST_NODE_TYPES.TSMethodSignature, // type T = {f(...args: any[]): unknown};
AST_NODE_TYPES.TSDeclareFunction, // declare function _8(...args: any[]): unknown;
].includes(node.type);
}

Expand Down