Skip to content

Commit

Permalink
[eslint] Consider useRef() as ... as constant
Browse files Browse the repository at this point in the history
Sometimes you need to use casts, eg: DefinitelyTyped/DefinitelyTyped#28884 (comment). This change ignores them and still allow you to omit the ref object from the deps list.

Test Plan: unit tests
  • Loading branch information
sophiebits committed Apr 5, 2020
1 parent 1fd4543 commit e86e306
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@ const ESLintTester = require('eslint').RuleTester;
const ReactHooksESLintPlugin = require('eslint-plugin-react-hooks');
const ReactHooksESLintRule = ReactHooksESLintPlugin.rules['exhaustive-deps'];

ESLintTester.setDefaultConfig({
parser: require.resolve('babel-eslint'),
parserOptions: {
ecmaVersion: 6,
sourceType: 'module',
},
});

/**
* A string template tag that removes padding from the left side of multi-line strings
* @param {Array} strings array of code strings (only one expected)
Expand Down Expand Up @@ -6441,11 +6433,65 @@ const tests = {
],
};

const testsTypescript = {
valid: [
{
// `ref` is still constant, despite the cast.
code: normalizeIndent`
function MyComponent() {
const ref = useRef() as React.MutableRefObject<HTMLDivElement>;
useEffect(() => {
console.log(ref.current);
}, []);
}
`,
},
],
invalid: [
{
// `local` is still non-constant, despite the cast.
code: normalizeIndent`
function MyComponent() {
const local = {} as string;
useEffect(() => {
console.log(local);
}, []);
}
`,
errors: [
{
message:
"React Hook useEffect has a missing dependency: 'local'. " +
'Either include it or remove the dependency array.',
suggestions: [
{
desc: 'Update the dependencies array to be: [local]',
output: normalizeIndent`
function MyComponent() {
const local = {} as string;
useEffect(() => {
console.log(local);
}, [local]);
}
`,
},
],
},
],
},
],
};

// For easier local testing
if (!process.env.CI) {
let only = [];
let skipped = [];
[...tests.valid, ...tests.invalid].forEach(t => {
[
...tests.valid,
...tests.invalid,
...testsTypescript.valid,
...testsTypescript.invalid,
].forEach(t => {
if (t.skip) {
delete t.skip;
skipped.push(t);
Expand All @@ -6466,7 +6512,20 @@ if (!process.env.CI) {
};
tests.valid = tests.valid.filter(predicate);
tests.invalid = tests.invalid.filter(predicate);
testsTypescript.valid = testsTypescript.valid.filter(predicate);
testsTypescript.invalid = testsTypescript.invalid.filter(predicate);
}

const eslintTester = new ESLintTester();
eslintTester.run('react-hooks', ReactHooksESLintRule, tests);
const parserOptions = {
ecmaVersion: 6,
sourceType: 'module',
};
new ESLintTester({
parser: require.resolve('babel-eslint'),
parserOptions,
}).run('react-hooks', ReactHooksESLintRule, tests);

new ESLintTester({
parser: require.resolve('@typescript-eslint/parser'),
parserOptions,
}).run('react-hooks', ReactHooksESLintRule, testsTypescript);
5 changes: 4 additions & 1 deletion packages/eslint-plugin-react-hooks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@
"url": "https://github.com/facebook/react/issues"
},
"engines": {
"node": ">=7"
"node": ">=10"
},
"homepage": "https://reactjs.org/",
"peerDependencies": {
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
},
"dependencies": {
"@typescript-eslint/parser": "^2.26.0"
}
}
5 changes: 4 additions & 1 deletion packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,13 @@ export default {
if (def.node.type !== 'VariableDeclarator') {
return false;
}
const init = def.node.init;
let init = def.node.init;
if (init == null) {
return false;
}
while (init.type === 'TSAsExpression') {
init = init.expression;
}
// Detect primitive constants
// const foo = 42
let declaration = def.node.parent;
Expand Down
57 changes: 57 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,11 @@
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==

"@types/eslint-visitor-keys@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==

"@types/estree@*":
version "0.0.42"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.42.tgz#8d0c1f480339efedb3e46070e22dd63e0430dd11"
Expand Down Expand Up @@ -1430,6 +1435,16 @@
dependencies:
"@types/yargs-parser" "*"

"@typescript-eslint/experimental-utils@2.26.0":
version "2.26.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.26.0.tgz#063390c404d9980767d76274df386c0aa675d91d"
integrity sha512-RELVoH5EYd+JlGprEyojUv9HeKcZqF7nZUGSblyAw1FwOGNnmQIU8kxJ69fttQvEwCsX5D6ECJT8GTozxrDKVQ==
dependencies:
"@types/json-schema" "^7.0.3"
"@typescript-eslint/typescript-estree" "2.26.0"
eslint-scope "^5.0.0"
eslint-utils "^2.0.0"

"@typescript-eslint/experimental-utils@^1.13.0":
version "1.13.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz#b08c60d780c0067de2fb44b04b432f540138301e"
Expand All @@ -1439,6 +1454,16 @@
"@typescript-eslint/typescript-estree" "1.13.0"
eslint-scope "^4.0.0"

"@typescript-eslint/parser@^2.26.0":
version "2.26.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.26.0.tgz#385463615818b33acb72a25b39c03579df93d76f"
integrity sha512-+Xj5fucDtdKEVGSh9353wcnseMRkPpEAOY96EEenN7kJVrLqy/EVwtIh3mxcUz8lsFXW1mT5nN5vvEam/a5HiQ==
dependencies:
"@types/eslint-visitor-keys" "^1.0.0"
"@typescript-eslint/experimental-utils" "2.26.0"
"@typescript-eslint/typescript-estree" "2.26.0"
eslint-visitor-keys "^1.1.0"

"@typescript-eslint/typescript-estree@1.13.0":
version "1.13.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz#8140f17d0f60c03619798f1d628b8434913dc32e"
Expand All @@ -1447,6 +1472,19 @@
lodash.unescape "4.0.1"
semver "5.5.0"

"@typescript-eslint/typescript-estree@2.26.0":
version "2.26.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.26.0.tgz#d8132cf1ee8a72234f996519a47d8a9118b57d56"
integrity sha512-3x4SyZCLB4zsKsjuhxDLeVJN6W29VwBnYpCsZ7vIdPel9ZqLfIZJgJXO47MNUkurGpQuIBALdPQKtsSnWpE1Yg==
dependencies:
debug "^4.1.1"
eslint-visitor-keys "^1.1.0"
glob "^7.1.6"
is-glob "^4.0.1"
lodash "^4.17.15"
semver "^6.3.0"
tsutils "^3.17.1"

"@webassemblyjs/ast@1.8.5":
version "1.8.5"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
Expand Down Expand Up @@ -5169,6 +5207,13 @@ eslint-utils@^1.3.1, eslint-utils@^1.4.3:
dependencies:
eslint-visitor-keys "^1.1.0"

eslint-utils@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.0.0.tgz#7be1cc70f27a72a76cd14aa698bcabed6890e1cd"
integrity sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==
dependencies:
eslint-visitor-keys "^1.1.0"

eslint-visitor-keys@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
Expand Down Expand Up @@ -13210,6 +13255,18 @@ tslib@^1, tslib@^1.10.0, tslib@^1.9.0, tslib@^1.9.3:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==

tslib@^1.8.1:
version "1.11.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==

tsutils@^3.17.1:
version "3.17.1"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==
dependencies:
tslib "^1.8.1"

tty-browserify@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
Expand Down

0 comments on commit e86e306

Please sign in to comment.