Repository: TypeScript
Issue: [decorator metadata] implicit runtime reference created
Labels: Bug,Rescheduled

# Bug Report

<!--
  Please fill in each section completely. Thank you!
-->

### 🔎 Search Terms

<!--
  What search terms did you use when trying to find an existing bug report?
  List them here so people in the future can find this one more easily.
-->

decorator metadata shadow same name generic
(also searched in the "Domain: Decorators" tag)

### 🕗 Version & Regression Information

<!-- When did you start seeing this bug occur?

"Bugs" that have existed in TS for a long time are very likely to be FAQs; refer to
  https://github.com/Microsoft/TypeScript/wiki/FAQ#common-bugs-that-arent-bugs

If possible, please try testing the nightly version of TS to see if it's already been fixed.
For npm: `typescript@next`
This is also the 'Nightly' version in the playground: http://www.typescriptlang.org/play/?ts=Nightly

Note: The TypeScript Playground can be used to try older versions of TypeScript.

Please keep and fill in the line that best applies:
-->
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about decorators

### ⏯ Playground Link

<!--
  A link to a TypeScript Playground "Share" link which shows this behavior

  The TypeScript Workbench can be used for more complex setups, try
  https://www.typescriptlang.org/dev/bug-workbench/

  As a last resort, you can link to a repo, but these will be slower for us to investigate.
-->
[Playground link with relevant code](https://www.typescriptlang.org/play?ts=4.1.3#code/JYWwDg9gTgLgBAbzgFQKYGd4F84DMoQhwDkAdAPRqbEDcAUHQCaoDGANgIZSp4CuAdixjAI-OMxYQAFKVkB9MFw4gAXHA78AngEo1GzfTqoAHpFhx2HdOjgBhTgC8HiOnDgABCRFdwQqGAAWEIwAPFQwAHxS4Wrh2i4+WHRYQA)

### 💻 Code

<!-- Please post the relevant code sample here as well-->
```ts
import { Test } from './Test';

declare function deco(..._param: any): any;

export class Clazz {
  @deco
  method<Test>(Test: Test) {

  }
}
```

### 🙁 Actual behavior

As far as TS's unused vars logic is concerned - the above code just creates a type reference on the generic `Test`:
![image](https://user-images.githubusercontent.com/7462525/107127241-a2f8c800-6869-11eb-8322-daddd4bf10ca.png)

However when you look at the generated code:

```js
__decorate([
    deco,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [typeof (_a = typeof Test !== "undefined" && Test) === "function" ? _a : Object]),
    __metadata("design:returntype", void 0)
], Clazz.prototype, "method", null);
```

The decorator actually creates an implicit value reference on the import `Test`.

Which means if you want to satisfy the `noUnusedLocals` error, you will (unknowingly) change the runtime behaviour.

### 🙂 Expected behavior


I think this is the intended behaviour? TBH I'm not entirely sure.
I haven't found any docs about how it's supposed to work.
I **think** it should _not_ be generating any runtime references.

```js
__decorate([
    deco,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], Clazz.prototype, "method", null);
```

For context, in @typescript-eslint we have a [scope analyser](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/scope-manager/src/referencer/ClassVisitor.ts) which also attempts to understand the runtime value references created by `emitDecoratorMetadata`. This understanding means lint rules like `no-unused-vars` and `consistent-type-imports` can understand the runtime code and provide correct lints/fixes. This logic was particularly added for `consistent-type-imports`, which broke people's code due to it not understanding that decorators created implicit value references.

A user presented a bug due to an (incorrect reference) - https://github.com/typescript-eslint/typescript-eslint/issues/2994.
Whilst investigating the fix, I want to ensure it's fixed correctly for all cases, including the one presented above.

If it's entirely intentional that this creates a value reference - then I'll make the referencer work the same way.