Skip to content

Commit d8c67a5

Browse files
fix(eslint-plugin): [no-shadow] ignore global module augmentation (typescript-eslint#2729)
1 parent 5df2719 commit d8c67a5

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

packages/eslint-plugin/docs/rules/no-shadow.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## Rule Details
44

55
This rule extends the base [`eslint/no-shadow`](https://eslint.org/docs/rules/no-shadow) rule.
6-
It adds support for TypeScript's `this` parameters, and adds options for TypeScript features.
6+
It adds support for TypeScript's `this` parameters and global augmentation, and adds options for TypeScript features.
77

88
## How to use
99

packages/eslint-plugin/src/rules/no-shadow.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
TSESLint,
44
AST_NODE_TYPES,
55
} from '@typescript-eslint/experimental-utils';
6+
import { ScopeType } from '@typescript-eslint/scope-manager';
67
import * as util from '../util';
78

89
type MessageIds = 'noShadow';
@@ -67,6 +68,16 @@ export default util.createRule<Options, MessageIds>({
6768
},
6869
],
6970
create(context, [options]) {
71+
/**
72+
* Check if a scope is a TypeScript module augmenting the global namespace.
73+
*/
74+
function isGlobalAugmentation(scope: TSESLint.Scope.Scope): boolean {
75+
return (
76+
(scope.type === ScopeType.tsModule && !!scope.block.global) ||
77+
(!!scope.upper && isGlobalAugmentation(scope.upper))
78+
);
79+
}
80+
7081
/**
7182
* Check if variable is a `this` parameter.
7283
*/
@@ -261,6 +272,11 @@ export default util.createRule<Options, MessageIds>({
261272
* @param {Scope} scope Fixme
262273
*/
263274
function checkForShadows(scope: TSESLint.Scope.Scope): void {
275+
// ignore global augmentation
276+
if (isGlobalAugmentation(scope)) {
277+
return;
278+
}
279+
264280
const variables = scope.variables;
265281

266282
for (const variable of variables) {

packages/eslint-plugin/tests/rules/no-shadow.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,49 @@ type Fn = (Foo: string) => typeof Foo;
116116
Foo: 'writable',
117117
},
118118
},
119+
// https://github.com/typescript-eslint/typescript-eslint/issues/2724
120+
{
121+
code: `
122+
declare global {
123+
interface ArrayConstructor {}
124+
}
125+
export {};
126+
`,
127+
options: [{ builtinGlobals: true }],
128+
},
129+
`
130+
declare global {
131+
const a: string;
132+
133+
namespace Foo {
134+
const a: number;
135+
}
136+
}
137+
export {};
138+
`,
139+
{
140+
code: `
141+
declare global {
142+
type A = 'foo';
143+
144+
namespace Foo {
145+
type A = 'bar';
146+
}
147+
}
148+
export {};
149+
`,
150+
options: [{ ignoreTypeValueShadow: false }],
151+
},
152+
{
153+
code: `
154+
declare global {
155+
const foo: string;
156+
type Fn = (foo: number) => void;
157+
}
158+
export {};
159+
`,
160+
options: [{ ignoreFunctionTypeParameterNameValueShadow: false }],
161+
},
119162
],
120163
invalid: [
121164
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy