Skip to content

Commit 342bd29

Browse files
authored
feat: ignore type annotations in no-restricted-globals (#19781)
1 parent e392895 commit 342bd29

File tree

3 files changed

+484
-2
lines changed

3 files changed

+484
-2
lines changed

docs/src/rules/no-restricted-globals.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,25 @@ function onClick() {
106106
```
107107

108108
:::
109+
110+
Restricted globals used in TypeScript type annotations—such as type references, interface inheritance, or class implementations—are ignored by this rule.
111+
112+
Examples of **correct** TypeScript code for "Promise", "Event", and "Window" global variable names:
113+
114+
::: correct
115+
116+
```ts
117+
/*eslint no-restricted-globals: ["error", "Promise", "Event", "Window"]*/
118+
119+
const fetchData: Promise<string> = fetchString();
120+
121+
interface CustomEvent extends Event {}
122+
123+
class CustomWindow implements Window {}
124+
125+
function handleClick(event: Event) {
126+
console.log(event);
127+
}
128+
```
129+
130+
:::

lib/rules/no-restricted-globals.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,27 @@
44
*/
55
"use strict";
66

7+
//------------------------------------------------------------------------------
8+
// Helpers
9+
//------------------------------------------------------------------------------
10+
11+
const TYPE_NODES = new Set([
12+
"TSTypeReference",
13+
"TSInterfaceHeritage",
14+
"TSClassImplements",
15+
"TSTypeQuery",
16+
"TSQualifiedName",
17+
]);
18+
719
//------------------------------------------------------------------------------
820
// Rule Definition
921
//------------------------------------------------------------------------------
1022

1123
/** @type {import('../types').Rule.RuleModule} */
1224
module.exports = {
1325
meta: {
26+
dialects: ["javascript", "typescript"],
27+
language: "javascript",
1428
type: "suggestion",
1529

1630
docs: {
@@ -100,20 +114,39 @@ module.exports = {
100114
return Object.hasOwn(restrictedGlobalMessages, name);
101115
}
102116

117+
/**
118+
* Check if the given reference occurs within a TypeScript type context.
119+
* @param {Reference} reference The variable reference to check.
120+
* @returns {boolean} Whether the reference is in a type context.
121+
* @private
122+
*/
123+
function isInTypeContext(reference) {
124+
const parent = reference.identifier.parent;
125+
126+
return TYPE_NODES.has(parent.type);
127+
}
128+
103129
return {
104130
Program(node) {
105131
const scope = sourceCode.getScope(node);
106132

107133
// Report variables declared elsewhere (ex: variables defined as "global" by eslint)
108134
scope.variables.forEach(variable => {
109135
if (!variable.defs.length && isRestricted(variable.name)) {
110-
variable.references.forEach(reportReference);
136+
variable.references.forEach(reference => {
137+
if (!isInTypeContext(reference)) {
138+
reportReference(reference);
139+
}
140+
});
111141
}
112142
});
113143

114144
// Report variables not declared at all
115145
scope.through.forEach(reference => {
116-
if (isRestricted(reference.identifier.name)) {
146+
if (
147+
isRestricted(reference.identifier.name) &&
148+
!isInTypeContext(reference)
149+
) {
117150
reportReference(reference);
118151
}
119152
});

0 commit comments

Comments
 (0)