Skip to content

fix(eslint-plugin): [no-shadow] report correctly on parameters of functions declared with the declare keyword #10543

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

Merged
4 changes: 4 additions & 0 deletions packages/eslint-plugin/src/rules/no-shadow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ const allowedFunctionVariableDefTypes = new Set([
AST_NODE_TYPES.TSCallSignatureDeclaration,
AST_NODE_TYPES.TSFunctionType,
AST_NODE_TYPES.TSMethodSignature,
AST_NODE_TYPES.TSEmptyBodyFunctionExpression,
AST_NODE_TYPES.TSDeclareFunction,
Copy link
Contributor

@yeonjuan yeonjuan Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ronami IMO, TSConstructSignatureDeclaration and TSConstructorType should also be added, what do you think?

// "ignoreFunctionTypeParameterNameValueShadow": true
const arg = 0;

declare const Foo: {
  foo: (arg: number) => void;
  new(arg: number): void; // 'arg' is already declared in the upper scope on line 2 column 7.
}
type Bar = new (arg: number) => void; // 'arg' is already declared in the upper scope on line 2 column 7.

Copy link
Member Author

@ronami ronami Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, definitely. Thank you @yeonjuan for catching this 👍

Copy link
Contributor

@yeonjuan yeonjuan Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ronami oops. I just edited the comment. I think we should add TSConstructorType also

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I just went over the list of nodes to make sure I didn't miss anything 🙈

Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks! 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @yeonjuan for the catch!

AST_NODE_TYPES.TSConstructSignatureDeclaration,
AST_NODE_TYPES.TSConstructorType,
]);

export default createRule<Options, MessageIds>({
Expand Down
168 changes: 168 additions & 0 deletions packages/eslint-plugin/tests/rules/no-shadow/no-shadow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,120 @@ interface Test {
},
{
code: `
const arg = 0;

declare function test(arg: string): typeof arg;
`,
errors: [
{
data: {
name: 'arg',
shadowedColumn: 7,
shadowedLine: 2,
},
messageId: 'noShadow',
},
],
options: [{ ignoreFunctionTypeParameterNameValueShadow: false }],
},
{
code: `
const arg = 0;

declare const test: (arg: string) => typeof arg;
`,
errors: [
{
data: {
name: 'arg',
shadowedColumn: 7,
shadowedLine: 2,
},
messageId: 'noShadow',
},
],
options: [{ ignoreFunctionTypeParameterNameValueShadow: false }],
},
{
code: `
const arg = 0;

declare class Test {
p1(arg: string): typeof arg;
}
`,
errors: [
{
data: {
name: 'arg',
shadowedColumn: 7,
shadowedLine: 2,
},
messageId: 'noShadow',
},
],
options: [{ ignoreFunctionTypeParameterNameValueShadow: false }],
},
{
code: `
const arg = 0;

declare const Test: {
new (arg: string): typeof arg;
};
`,
errors: [
{
data: {
name: 'arg',
shadowedColumn: 7,
shadowedLine: 2,
},
messageId: 'noShadow',
},
],
options: [{ ignoreFunctionTypeParameterNameValueShadow: false }],
},
{
code: `
const arg = 0;

type Bar = new (arg: number) => typeof arg;
`,
errors: [
{
data: {
name: 'arg',
shadowedColumn: 7,
shadowedLine: 2,
},
messageId: 'noShadow',
},
],
options: [{ ignoreFunctionTypeParameterNameValueShadow: false }],
},
{
code: `
const arg = 0;

declare namespace Lib {
function test(arg: string): typeof arg;
}
`,
errors: [
{
data: {
name: 'arg',
shadowedColumn: 7,
shadowedLine: 2,
},
messageId: 'noShadow',
},
],
options: [{ ignoreFunctionTypeParameterNameValueShadow: false }],
},
{
code: `
import type { foo } from './foo';
function doThing(foo: number) {}
`,
Expand Down Expand Up @@ -617,6 +731,60 @@ const arg = 0;

interface Test {
p1(arg: string): typeof arg;
}
`,
options: [{ ignoreFunctionTypeParameterNameValueShadow: true }],
},
{
code: `
const arg = 0;

declare function test(arg: string): typeof arg;
`,
options: [{ ignoreFunctionTypeParameterNameValueShadow: true }],
},
{
code: `
const arg = 0;

declare const test: (arg: string) => typeof arg;
`,
options: [{ ignoreFunctionTypeParameterNameValueShadow: true }],
},
{
code: `
const arg = 0;

declare class Test {
p1(arg: string): typeof arg;
}
`,
options: [{ ignoreFunctionTypeParameterNameValueShadow: true }],
},
{
code: `
const arg = 0;

declare const Test: {
new (arg: string): typeof arg;
};
`,
options: [{ ignoreFunctionTypeParameterNameValueShadow: true }],
},
{
code: `
const arg = 0;

type Bar = new (arg: number) => typeof arg;
`,
options: [{ ignoreFunctionTypeParameterNameValueShadow: true }],
},
{
code: `
const arg = 0;

declare namespace Lib {
function test(arg: string): typeof arg;
}
`,
options: [{ ignoreFunctionTypeParameterNameValueShadow: true }],
Expand Down
Loading