Skip to content

Commit 395e26b

Browse files
committed
[New] no-extraneous-dependencies: added includeTypes option to validate type imports
Fixes import-js#2542
1 parent 74f39d9 commit 395e26b

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1313
- [`no-anonymous-default-export`]: add `allowNew` option ([#2505], thanks [@DamienCassou])
1414
- [`order`]: Add `distinctGroup` option ([#2395], thanks [@hyperupcall])
1515
- [`no-extraneous-dependencies`]: Add `includeInternal` option ([#2541], thanks [@bdwain])
16+
- [`no-extraneous-dependencies`]: Add `includeTypes` option ([#2543], thanks [@bdwain])
1617

1718
### Fixed
1819
- [`order`]: move nested imports closer to main import entry ([#2396], thanks [@pri1311])

docs/rules/no-extraneous-dependencies.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# import/no-extraneous-dependencies: Forbid the use of extraneous packages
22

33
Forbid the import of external modules that are not declared in the `package.json`'s `dependencies`, `devDependencies`, `optionalDependencies`, `peerDependencies`, or `bundledDependencies`.
4-
The closest parent `package.json` will be used. If no `package.json` is found, the rule will not lint anything. This behavior can be changed with the rule option `packageDir`. Normally ignores imports of modules marked internal, but this can be changed with the rule option `includeInternal`.
4+
The closest parent `package.json` will be used. If no `package.json` is found, the rule will not lint anything. This behavior can be changed with the rule option `packageDir`. Normally ignores imports of modules marked internal, but this can be changed with the rule option `includeInternal`. Type imports can be verified by specifying `includeTypes`.
55

66
Modules have to be installed for this rule to work.
77

@@ -31,10 +31,10 @@ You can also use an array of globs instead of literal booleans:
3131

3232
When using an array of globs, the setting will be set to `true` (no errors reported) if the name of the file being linted matches a single glob in the array, and `false` otherwise.
3333

34-
There is a boolean option called `includeInternal`, which enables the checking of internal modules, which are otherwise ignored by this rule.
34+
There are 2 boolean options to opt into checking extra imports that are normally ignored: `includeInternal`, which enables the checking of internal modules, and `includeTypes`, which enables checking of type imports in TypeScript.
3535

3636
```js
37-
"import/no-extraneous-dependencies": ["error", {"includeInternal": true}]
37+
"import/no-extraneous-dependencies": ["error", {"includeInternal": true, "includeTypes": true}]
3838
```
3939

4040
Also there is one more option called `packageDir`, this option is to specify the path to the folder containing package.json.
@@ -109,6 +109,9 @@ var foo = require('"@generated/foo"');
109109
/* eslint import/no-extraneous-dependencies: ["error", {"includeInternal": true}] */
110110
import foo from './foo';
111111
var foo = require('./foo');
112+
113+
/* eslint import/no-extraneous-dependencies: ["error", {"includeTypes": true}] */
114+
import type { MyType } from 'foo';
112115
```
113116

114117

@@ -123,6 +126,7 @@ import test from 'ava';
123126
import find from 'lodash.find';
124127
import isArray from 'lodash.isarray';
125128
import foo from '"@generated/foo"';
129+
import type { MyType } from 'foo';
126130

127131
/* eslint import/no-extraneous-dependencies: ["error", {"peerDependencies": true}] */
128132
import react from 'react';

src/rules/no-extraneous-dependencies.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,10 @@ function checkDependencyDeclaration(deps, packageName, declarationStatus) {
175175
}
176176

177177
function reportIfMissing(context, deps, depsOptions, node, name) {
178-
// Do not report when importing types
178+
// Do not report when importing types unless option is enabled
179179
if (
180-
node.importKind === 'type' ||
181-
node.importKind === 'typeof'
180+
!depsOptions.verifyTypeImports &&
181+
(node.importKind === 'type' || node.importKind === 'typeof')
182182
) {
183183
return;
184184
}
@@ -267,6 +267,7 @@ module.exports = {
267267
'bundledDependencies': { 'type': ['boolean', 'array'] },
268268
'packageDir': { 'type': ['string', 'array'] },
269269
'includeInternal': { 'type': ['boolean'] },
270+
'includeTypes': { 'type': ['boolean'] },
270271
},
271272
'additionalProperties': false,
272273
},
@@ -284,6 +285,7 @@ module.exports = {
284285
allowPeerDeps: testConfig(options.peerDependencies, filename) !== false,
285286
allowBundledDeps: testConfig(options.bundledDependencies, filename) !== false,
286287
verifyInternalDeps: !!options.includeInternal,
288+
verifyTypeImports: !!options.includeTypes,
287289
};
288290

289291
return moduleVisitor((source, node) => {

tests/src/rules/no-extraneous-dependencies.js

+21
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,18 @@ describe('TypeScript', () => {
435435
message: "'a' should be listed in the project's dependencies, not devDependencies.",
436436
}],
437437
}, parserConfig)),
438+
439+
test(Object.assign({
440+
code: 'import type T from "a";',
441+
options: [{
442+
packageDir: packageDirWithTypescriptDevDependencies,
443+
devDependencies: false,
444+
includeTypes: true,
445+
}],
446+
errors: [{
447+
message: "'a' should be listed in the project's dependencies, not devDependencies.",
448+
}],
449+
}, parserConfig)),
438450
],
439451
});
440452
});
@@ -454,5 +466,14 @@ typescriptRuleTester.run('no-extraneous-dependencies typescript type imports', r
454466
}),
455467
],
456468
invalid: [
469+
test({
470+
code: 'import type { MyType } from "not-a-dependency";',
471+
options: [{ includeTypes: true }],
472+
filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'),
473+
parser: parsers.BABEL_OLD,
474+
errors: [{
475+
message: `'not-a-dependency' should be listed in the project's dependencies. Run 'npm i -S not-a-dependency' to add it`,
476+
}],
477+
}),
457478
],
458479
});

0 commit comments

Comments
 (0)