Skip to content

Bug: [consistent-type-imports] False positive when using DI and decorators (tsyringe) #5903

Closed
@ajmnz

Description

@ajmnz

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have searched for related issues and found none that matched my issue.
  • I have read the FAQ and my problem is not listed.

Playground Link

https://typescript-eslint.io/play/#ts=4.8.4&sourceType=module&code=GYVwdgxgLglg9mABDMArAptAhgIwDboA8AKgHwAUAlAFyLlRYBOA5ulLcZYgLymIBucGABNEAbwBQiRIzYhGSUJFgI6DFmw40BQ0ZOnSpiAL4BuCcYkSA9NcQABKAGcAtDGZg4siTAC2ABy8ocUQAISYTRGBGOF9EAHIAOmscJnjzCXsUDGx8dCoJCDwsJydEADE4OHEjCAQnKEYQaC9yf0YYfiwodERUxlpwxi4xS2MgA&eslintrc=N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6MgeyeUuX0Ra0ipWpQC2xDtHyo0kRNGhTI4MAF8QaoA&tsconfig=N4KABGBEDGD2C2AHAlgGwKYCcDyiAuysAdgM6QBcYoEEkJemy0eAcgK6qoDCAFutAGsylBm3QAacDUjp4yPABF+sTAEM8KgLLo8qgCbrVFMKIlTa6AB6IsyeOiK7USuGo2ZhJzGKkBfEL5AA

Repro Code

function injectable<T>(): (target: T) => void {
  return function (target: T): void {
    
  };
}

import { Bar } from './bar'; // Error: All imports in the declaration are only used as types.

@injectable()
class Foo {
  constructor(private bar: Bar) {}
}

ESLint Config

module.exports = {
  parser: "@typescript-eslint/parser",
  rules: {
    "@typescript-eslint/consistent-type-imports": "error"
  },
};

tsconfig

{
  "compilerOptions": {
    "strictNullChecks": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  }
}

Expected Result

I expected that #2751 (#2559) would've fixed this and the rule wouldn't have assumed that it is only used as a type, but turns out it only catches decorators from within the constructor:

import { Bar } from './bar'; // ok

class Foo {
  constructor(@deco(() => Bar) private bar: Bar) {}
}
import { Bar } from './bar'; // Expected ok, but got Error: All imports in the declaration are only used as types.

@injectable()
class Foo {
  constructor(private bar: Bar) {}
}

Actual Result

The rule assumes Bar is used as a type, causing the DI library (in the case tsyringe) to be unable to inject the dependencies (Bar) at runtime. This is pretty similar to the issue with Nest.js (#2559)

Additional Info

No response

Versions

package version
@typescript-eslint/eslint-plugin 5.41.0
@typescript-eslint/parser playground default
TypeScript 4.8.4
ESLint 8.15.0
node playground default

Metadata

Metadata

Assignees

No one assigned

    Labels

    fix: user errorissue was fixed by correcting the configuration / correcting the codepackage: eslint-pluginIssues related to @typescript-eslint/eslint-plugin

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions