Skip to content

Commit 2ee0b7b

Browse files
author
Geraint White
committed
[Fix] order: support type imports
1 parent e871a9a commit 2ee0b7b

File tree

3 files changed

+39
-29
lines changed

3 files changed

+39
-29
lines changed

docs/rules/order.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import baz from './bar/baz';
2424
import main from './';
2525
// 7. "object"-imports (only available in TypeScript)
2626
import log = console.log;
27+
// 8. "type" imports (only available in Flow and TypeScript)
28+
import type { Foo } from 'foo';
2729
```
2830

2931
Unassigned imports are ignored, as the order they are imported in may be important.
@@ -80,7 +82,7 @@ This rule supports the following options:
8082
### `groups: [array]`:
8183

8284
How groups are defined, and the order to respect. `groups` must be an array of `string` or [`string`]. The only allowed `string`s are:
83-
`"builtin"`, `"external"`, `"internal"`, `"unknown"`, `"parent"`, `"sibling"`, `"index"`, `"object"`.
85+
`"builtin"`, `"external"`, `"internal"`, `"unknown"`, `"parent"`, `"sibling"`, `"index"`, `"object"`, `"type"`.
8486
The enforced order is the same as the order of each element in a group. Omitted types are implicitly grouped together as the last element. Example:
8587
```js
8688
[
@@ -96,7 +98,7 @@ The default value is `["builtin", "external", "parent", "sibling", "index"]`.
9698
You can set the options like this:
9799

98100
```js
99-
"import/order": ["error", {"groups": ["index", "sibling", "parent", "internal", "external", "builtin", "object"]}]
101+
"import/order": ["error", {"groups": ["index", "sibling", "parent", "internal", "external", "builtin", "object", "type"]}]
100102
```
101103

102104
### `pathGroups: [array of objects]`:

src/rules/order.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ function mutateRanksToAlphabetize(imported, alphabetizeOptions) {
265265
if (!Array.isArray(acc[importedItem.rank])) {
266266
acc[importedItem.rank] = [];
267267
}
268-
acc[importedItem.rank].push(importedItem.value);
268+
acc[importedItem.rank].push(`${importedItem.value}-${importedItem.node.importKind}`);
269269
return acc;
270270
}, {});
271271

@@ -290,7 +290,7 @@ function mutateRanksToAlphabetize(imported, alphabetizeOptions) {
290290

291291
// mutate the original group-rank with alphabetized-rank
292292
imported.forEach(function(importedItem) {
293-
importedItem.rank = alphabetizedRanks[importedItem.value];
293+
importedItem.rank = alphabetizedRanks[`${importedItem.value}-${importedItem.node.importKind}`];
294294
});
295295
}
296296

@@ -310,6 +310,8 @@ function computeRank(context, ranks, importEntry, excludedImportTypes) {
310310
let rank;
311311
if (importEntry.type === 'import:object') {
312312
impType = 'object';
313+
} else if (importEntry.node.importKind === 'type') {
314+
impType = 'type';
313315
} else {
314316
impType = importType(importEntry.value, context);
315317
}
@@ -350,7 +352,7 @@ function isModuleLevelRequire(node) {
350352
);
351353
}
352354

353-
const types = ['builtin', 'external', 'internal', 'unknown', 'parent', 'sibling', 'index', 'object'];
355+
const types = ['builtin', 'external', 'internal', 'unknown', 'parent', 'sibling', 'index', 'object', 'type'];
354356

355357
// Creates an object with type-rank pairs.
356358
// Example: { index: 0, sibling: 1, parent: 1, external: 1, builtin: 2, internal: 2 }

tests/src/rules/order.js

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2186,12 +2186,13 @@ context('TypeScript', function () {
21862186
{
21872187
code: `
21882188
import c from 'Bar';
2189-
import type { C } from 'Bar';
21902189
import b from 'bar';
21912190
import a from 'foo';
2192-
import type { A } from 'foo';
21932191
21942192
import index from './';
2193+
2194+
import type { C } from 'Bar';
2195+
import type { A } from 'foo';
21952196
`,
21962197
parser,
21972198
options: [
@@ -2208,12 +2209,13 @@ context('TypeScript', function () {
22082209
{
22092210
code: `
22102211
import a from 'foo';
2211-
import type { A } from 'foo';
22122212
import b from 'bar';
22132213
import c from 'Bar';
2214-
import type { C } from 'Bar';
22152214
22162215
import index from './';
2216+
2217+
import type { A } from 'foo';
2218+
import type { C } from 'Bar';
22172219
`,
22182220
parser,
22192221
options: [
@@ -2233,20 +2235,22 @@ context('TypeScript', function () {
22332235
code: `
22342236
import b from 'bar';
22352237
import c from 'Bar';
2236-
import type { C } from 'Bar';
22372238
import a from 'foo';
2238-
import type { A } from 'foo';
22392239
22402240
import index from './';
2241+
2242+
import type { A } from 'foo';
2243+
import type { C } from 'Bar';
22412244
`,
22422245
output: `
22432246
import c from 'Bar';
2244-
import type { C } from 'Bar';
22452247
import b from 'bar';
22462248
import a from 'foo';
2247-
import type { A } from 'foo';
22482249
22492250
import index from './';
2251+
2252+
import type { C } from 'Bar';
2253+
import type { A } from 'foo';
22502254
`,
22512255
parser,
22522256
options: [
@@ -2255,12 +2259,12 @@ context('TypeScript', function () {
22552259
alphabetize: { order: 'asc' },
22562260
},
22572261
],
2258-
errors: [
2259-
{
2260-
message: semver.satisfies(eslintPkg.version, '< 3')
2261-
? '`bar` import should occur after import of `Bar`'
2262-
: /(`bar` import should occur after import of `Bar`)|(`Bar` import should occur before import of `bar`)/,
2263-
},
2262+
errors: semver.satisfies(eslintPkg.version, '< 3') ? [
2263+
{ message: '`Bar` import should occur before import of `bar`' },
2264+
{ message: '`Bar` import should occur before import of `foo`' },
2265+
] : [
2266+
{ message: /(`Bar` import should occur before import of `bar`)|(`bar` import should occur after import of `Bar`)/ },
2267+
{ message: /(`Bar` import should occur before import of `foo`)|(`foo` import should occur after import of `Bar`)/ },
22642268
],
22652269
},
22662270
parserConfig,
@@ -2270,21 +2274,23 @@ context('TypeScript', function () {
22702274
{
22712275
code: `
22722276
import a from 'foo';
2273-
import type { A } from 'foo';
22742277
import c from 'Bar';
2275-
import type { C } from 'Bar';
22762278
import b from 'bar';
22772279
22782280
import index from './';
2281+
2282+
import type { C } from 'Bar';
2283+
import type { A } from 'foo';
22792284
`,
22802285
output: `
22812286
import a from 'foo';
2282-
import type { A } from 'foo';
22832287
import b from 'bar';
22842288
import c from 'Bar';
2285-
import type { C } from 'Bar';
22862289
22872290
import index from './';
2291+
2292+
import type { A } from 'foo';
2293+
import type { C } from 'Bar';
22882294
`,
22892295
parser,
22902296
options: [
@@ -2293,12 +2299,12 @@ context('TypeScript', function () {
22932299
alphabetize: { order: 'desc' },
22942300
},
22952301
],
2296-
errors: [
2297-
{
2298-
message: semver.satisfies(eslintPkg.version, '< 3')
2299-
? '`bar` import should occur before import of `Bar`'
2300-
: /(`bar` import should occur before import of `Bar`)|(`Bar` import should occur after import of `bar`)/,
2301-
},
2302+
errors: semver.satisfies(eslintPkg.version, '< 3') ? [
2303+
{ message: '`bar` import should occur before import of `Bar`' },
2304+
{ message: '`foo` import should occur before import of `Bar`' },
2305+
] : [
2306+
{ message: /(`bar` import should occur before import of `Bar`)|(`Bar` import should occur after import of `bar`)/ },
2307+
{ message: /(`foo` import should occur before import of `Bar`)|(`Bar` import should occur after import of `foo`)/ },
23022308
],
23032309
},
23042310
parserConfig,

0 commit comments

Comments
 (0)