eslint-plugin-import: import/no-cycle should not trigger for TypeScript type imports

Repro

{
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: './tsconfig.json',
  },
  plugins: [
    '@typescript-eslint',
    'react-hooks',
  ],
  extends: [
    'airbnb',
    'plugin:import/typescript',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
  ],
  // ...
}
// store.ts
import orders from 'entities/orders/reducers';

const rootReducer = combineReducers({
  orders,
});

export type AppState = ReturnType<typeof rootReducer>
// entities/orders/reducers.ts
import {SetOrdersAction} from './actions';

export default createReducer(initialState, {
 ...
})
// entities/orders/actions.ts
import {ThunkAction} from 'redux-thunk';

import {AppState} from 'store';

export const pollOrders = (): ThunkAction<void, AppState, void, SetOrdersAction> => (
   ...
);

Actual Result

There is the store (imports reducers), reducers (imports actions), and actions (imports store type) in application. import/no-cycle rule alerts about cycle dependency, but only type information are cycled and it will be skipped at runtime

Related https://github.com/benmosher/eslint-plugin-import/issues/1343 https://github.com/typescript-eslint/typescript-eslint/issues/843

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 66
  • Comments: 19 (7 by maintainers)

Most upvoted comments

Hi, using import type { x } from 'y'; solved problem for me.

Flow has import type; TS does not - I’m not sure how we could statically know it’s a type on the import side, especially with d.ts files being a thing.

As of TypeScript 3.8, import type is available in TS too, it might help with the implementation.

I can confirm, that using syntax import type { x } from 'y' works without problem.

@RebeccaStevens In case of a circular dependency, as enums are compiled to values in TS, it’s fair that the rule applies. You might have issues in situations where you’re expecting a value to be defined but it’s not yet due to the circular dependency issue, which can cause unpredictable problems depending on where the value is used, which is the point of the rule.

So enums should be treated with the same regards as any other imported value 😃

With Typescript’s new import type syntax, this error goes away.

import type is a solution for types. Enums are not types…

I have some files in my codebase which exports types and also enums. Once I use import type { x } from 'y' syntax, TypeScript complains and raises following error; 'MyEnum' cannot be used as a value because it was imported using 'import type'.ts(1361). So, I had to exclude this rule from my rules list. If I import my enum as before, this time I get cycle dependency error. So, import type { x } from 'y' is not a solution for enums, I had to exclude this rule from my rule set.

nope, nobody’s sent a PR afaict.