diff --git a/src/rules/defineFlowType.js b/src/rules/defineFlowType.js index 5caf26a..f32a4f4 100644 --- a/src/rules/defineFlowType.js +++ b/src/rules/defineFlowType.js @@ -1,8 +1,23 @@ -const schema = []; +const schema = [ + { + properties: { + ignoreTypes: { + items: { + type: 'string', + }, + type: 'array', + }, + }, + type: 'object', + }, +]; const create = (context) => { let globalScope; + const [firstOption] = context.options; + const ignoreTypes = firstOption ? firstOption.ignoreTypes : []; + // do nearly the same thing that eslint does for config globals // https://github.com/eslint/eslint/blob/v2.0.0/lib/eslint.js#L118-L194 const makeDefined = (ident) => { @@ -12,6 +27,10 @@ const create = (context) => { for (ii = globalScope.through.length - 1; ii >= 0; ii--) { const ref = globalScope.through[ii]; + if (ignoreTypes.includes(ident.name)) { + return; + } + if (ref.identifier.name === ident.name) { // use "__defineGeneric" since we don't have a reference to "escope.Variable" diff --git a/tests/rules/assertions/defineFlowType.js b/tests/rules/assertions/defineFlowType.js index 8e421c0..ef509bc 100644 --- a/tests/rules/assertions/defineFlowType.js +++ b/tests/rules/assertions/defineFlowType.js @@ -2,6 +2,7 @@ import { RuleTester, } from 'eslint'; import noUndefRule from 'eslint/lib/rules/no-undef'; +import defineFlowType from '../../../src/rules/defineFlowType'; const VALID_WITH_DEFINE_FLOW_TYPE = [ { @@ -146,6 +147,26 @@ type Foo = $ReadOnly<{}>`, }, }, }, + + /** + * There is unobvious behavior. + * We used Foo type and it became global variable. + * noUndefRule will not pay attention to Foo variable with defineFlowType. + * It can be fixed with ignoreTypes option + */ + { + code: ` +type A = {foo: Foo}; + +Foo() +`, + + // There are two errors one for type another for global var + errors: [ + '\'Foo\' is not defined.', + '\'Foo\' is not defined.', + ], + }, ]; const ALWAYS_INVALID = [ @@ -221,6 +242,32 @@ const ALWAYS_VALID = [ }); } +{ + const ruleTester = new RuleTester({ + parser: require.resolve('babel-eslint'), + rules: { + 'define-flow-type': [1, {ignoreTypes: ['Foo']}], + }, + }); + + ruleTester.defineRule('define-flow-type', defineFlowType); + ruleTester.run('no-undef must trigger an error when define-flow-type is used with ignoreTypes option', noUndefRule, { + invalid: [ + { + code: ` +type A = {foo: Foo}; +Foo(); +`, + errors: [ + '\'Foo\' is not defined.', + '\'Foo\' is not defined.', + ], + }, + ], + valid: [], + }); +} + export default { invalid: [], valid: [