Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[consistent-type-imports] conflict with importsNotUsedAsValues compile option. #4268

Closed
3 tasks done
CatsMiaow opened this issue Dec 7, 2021 · 1 comment
Closed
3 tasks done
Labels
package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin working as intended Issues that are closed as they are working as intended

Comments

@CatsMiaow
Copy link

CatsMiaow commented Dec 7, 2021

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have read the FAQ and my problem is not listed.

Repro

{
  "rules": {
    "@typescript-eslint/consistent-type-imports": "error"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "importsNotUsedAsValues": "error",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}
import type { Request, Response } from 'express';

@Get()
public hello(@Req() req: Request, @Res() res: Response): void {}

Expected Result

Actual Result

In the code, Request and Response are used only as type information.

image

image

Additional Info

// This code also causes the same problem.
import type { Redis } from 'ioredis';

class Test {
  constructor(@Inject(REDIS) private redis: Redis) {}
}

Versions

package version
@typescript-eslint/eslint-plugin 5.6.0
@typescript-eslint/parser 5.6.0
TypeScript 4.5.2
ESLint 8.3.0
node 16.13.0
@CatsMiaow CatsMiaow added package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin triage Waiting for maintainers to take a look labels Dec 7, 2021
@bradzacher
Copy link
Member

TS is technically correct here - but it's inconsistent in its behaviour and impossible for us to properly reproduce in the lint rule.

emitDecoratorMetadata implicitly uses values - for example if you import a class and use it, TS will emit code which uses the class at runtime, even though your code as written only uses it as a type. This is consistent for most things that can be assigned to a type annotation - TS will implicitly use the value at runtime.

However if you pass an actual type (an interface, for example), TS will not use it as a value, and will instead use it as a type - it will use the type to inform the codegen. For example an interface will cause TS to emit Object, but a function type will cause TS to emit Function. TS does this across module boundaries (violating its own isolated modules build restrictions).

This is one of the few, rare cases where the two will disagree. Unfortunately because you need type information to do this, we cannot exactly replicate this behaviour in our lint rule. See other discussion on #3108.

You should either use the TS option, or our lint rule - not both.

@bradzacher bradzacher added working as intended Issues that are closed as they are working as intended and removed triage Waiting for maintainers to take a look labels Dec 7, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin working as intended Issues that are closed as they are working as intended
Projects
None yet
Development

No branches or pull requests

2 participants