Skip to content

Commit 10ad067

Browse files
committed
feat(eslint-plugin-react-hooks): convert to typescript and package type declarations
This change converts the eslint hooks plugin to typescript, which also allows us to include type declarations in the package, for those using [typescript eslint configs](https://eslint.org/blog/2025/01/eslint-v9.18.0-released/#stable-typescript-configuration-file-support).
1 parent 4b38c7c commit 10ad067

File tree

2 files changed

+17
-15
lines changed

2 files changed

+17
-15
lines changed

packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ const rule = {
237237
return false;
238238
}
239239
const def = resolved.defs[0];
240-
if (!def) {
240+
if (def == null) {
241241
return false;
242242
}
243243
// Look for `let stuff = ...`
@@ -246,7 +246,7 @@ const rule = {
246246
return false;
247247
}
248248
let init = defNode.init;
249-
if (!init) {
249+
if (init == null) {
250250
return false;
251251
}
252252
while (init.type === 'TSAsExpression' || init.type === 'AsExpression') {
@@ -255,13 +255,13 @@ const rule = {
255255
// Detect primitive constants
256256
// const foo = 42
257257
let declaration = defNode.parent;
258-
if (!declaration && componentScope) {
258+
if (declaration == null && componentScope) {
259259
// This might happen if variable is declared after the callback.
260260
// In that case ESLint won't set up .parent refs.
261261
// So we'll set them up manually.
262262
fastFindReferenceWithParent(componentScope.block, def.node.id);
263263
declaration = def.node.parent;
264-
if (!declaration) {
264+
if (declaration == null) {
265265
return false;
266266
}
267267
}
@@ -406,13 +406,13 @@ const rule = {
406406
break;
407407
}
408408
}
409-
if (!fnScope) {
409+
if (fnScope == null) {
410410
return false;
411411
}
412412
// Does this function capture any values
413413
// that are in pure scopes (aka render)?
414414
for (const ref of fnScope.through) {
415-
if (!ref.resolved) {
415+
if (ref.resolved == null) {
416416
continue;
417417
}
418418
if (
@@ -488,7 +488,7 @@ const rule = {
488488
node,
489489
reference.identifier,
490490
);
491-
if (!referenceNode) {
491+
if (referenceNode == null) {
492492
continue;
493493
}
494494
const dependencyNode = getDependency(referenceNode);
@@ -525,7 +525,7 @@ const rule = {
525525
}
526526

527527
const def = reference.resolved.defs[0];
528-
if (!def) {
528+
if (def == null) {
529529
continue;
530530
}
531531
// Ignore references to the function itself as it's not defined yet.
@@ -1707,7 +1707,7 @@ function scanForConstructions({
17071707
const constructions = declaredDependencies
17081708
.map(({key}) => {
17091709
const ref = componentScope.variables.find(v => v.name === key);
1710-
if (!ref) {
1710+
if (ref == null) {
17111711
return null;
17121712
}
17131713

packages/eslint-plugin-react-hooks/src/index.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import RulesOfHooks from './RulesOfHooks';
88
import ExhaustiveDeps from './ExhaustiveDeps';
99
import type {ESLint, Linter, Rule} from 'eslint';
1010

11-
const packageJson: {name: string; version: string} = require('../package.json');
12-
1311
// All rules
1412
const rules = {
1513
'rules-of-hooks': RulesOfHooks,
@@ -30,7 +28,9 @@ const legacyRecommendedConfig = {
3028

3129
// Plugin object
3230
const plugin = {
33-
meta: {name: packageJson.name, version: packageJson.version},
31+
// TODO: Make this more dynamic to populate version from package.json.
32+
// This can be done by injecting at build time, since importing the package.json isn't an option in Meta
33+
meta: {name: 'eslint-plugin-react-hooks'},
3434
rules,
3535
configs: {
3636
/** Legacy recommended config, to be used with rc-based configurations */
@@ -55,8 +55,10 @@ const plugin = {
5555
},
5656
} satisfies ESLint.Plugin;
5757

58-
// These exports are for backwards compatibility with eslint versions before v9
5958
const configs = plugin.configs;
60-
export {configs, rules};
59+
const meta = plugin.meta;
60+
export {configs, meta, rules};
6161

62-
export default plugin;
62+
// TODO: If the plugin is ever updated to be pure ESM and drops support for rc-based configs, then it should be exporting the plugin as default
63+
// instead of individual named exports.
64+
// export default plugin;

0 commit comments

Comments
 (0)