From bd970019a86a692f9a6f9e5c74292719081ffa50 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sat, 5 Sep 2020 15:51:31 -0700 Subject: [PATCH] fix(scope-manager): treat type imports as both values and types Fixes #2453 --- .../tests/rules/no-unused-vars.test.ts | 5 ++ .../src/definition/ImportBindingDefinition.ts | 7 +- .../fixtures/import/type-default-value.ts | 5 ++ .../import/type-default-value.ts.shot | 69 +++++++++++++++++++ .../fixtures/import/type-default.ts.shot | 19 ++--- .../tests/fixtures/import/type-named-value.ts | 5 ++ .../fixtures/import/type-named-value.ts.shot | 69 +++++++++++++++++++ .../tests/fixtures/import/type-named.ts.shot | 19 ++--- 8 files changed, 174 insertions(+), 24 deletions(-) create mode 100644 packages/scope-manager/tests/fixtures/import/type-default-value.ts create mode 100644 packages/scope-manager/tests/fixtures/import/type-default-value.ts.shot create mode 100644 packages/scope-manager/tests/fixtures/import/type-named-value.ts create mode 100644 packages/scope-manager/tests/fixtures/import/type-named-value.ts.shot diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts index aa795ed5d767..af6ff089d4ba 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts @@ -783,6 +783,11 @@ type StyledPaymentProps = { export const StyledPayment = styled.div\`\`; `, + // https://github.com/typescript-eslint/typescript-eslint/issues/2453 + ` +import type { foo } from './a'; +export type Bar = typeof foo; + `, ], invalid: [ diff --git a/packages/scope-manager/src/definition/ImportBindingDefinition.ts b/packages/scope-manager/src/definition/ImportBindingDefinition.ts index e3e1d8401401..874edadf5e94 100644 --- a/packages/scope-manager/src/definition/ImportBindingDefinition.ts +++ b/packages/scope-manager/src/definition/ImportBindingDefinition.ts @@ -30,15 +30,10 @@ class ImportBindingDefinition extends DefinitionBase< decl: TSESTree.ImportDeclaration | TSESTree.TSImportEqualsDeclaration, ) { super(DefinitionType.ImportBinding, name, node, decl); - if ('importKind' in this.parent && this.parent.importKind === 'type') { - this.isVariableDefinition = false; - } else { - this.isVariableDefinition = true; - } } public readonly isTypeDefinition = true; - public readonly isVariableDefinition: boolean; + public readonly isVariableDefinition = true; } export { ImportBindingDefinition }; diff --git a/packages/scope-manager/tests/fixtures/import/type-default-value.ts b/packages/scope-manager/tests/fixtures/import/type-default-value.ts new file mode 100644 index 000000000000..0fcbdf3d72de --- /dev/null +++ b/packages/scope-manager/tests/fixtures/import/type-default-value.ts @@ -0,0 +1,5 @@ +//// @sourceType = module + +import type foo from 'foo'; + +type T = typeof foo; diff --git a/packages/scope-manager/tests/fixtures/import/type-default-value.ts.shot b/packages/scope-manager/tests/fixtures/import/type-default-value.ts.shot new file mode 100644 index 000000000000..d79d510a485d --- /dev/null +++ b/packages/scope-manager/tests/fixtures/import/type-default-value.ts.shot @@ -0,0 +1,69 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`import type-default-value 1`] = ` +ScopeManager { + variables: Array [ + Variable$1 { + defs: Array [ + ImportBindingDefinition$1 { + name: Identifier<"foo">, + node: ImportDefaultSpecifier$1, + }, + ], + name: "foo", + references: Array [ + Reference$1 { + identifier: Identifier<"foo">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$1, + }, + ], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$2 { + defs: Array [ + TypeDefinition$2 { + name: Identifier<"T">, + node: TSTypeAliasDeclaration$2, + }, + ], + name: "T", + references: Array [], + isValueVariable: false, + isTypeVariable: true, + }, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$3, + isStrict: false, + references: Array [], + set: Map {}, + type: "global", + upper: null, + variables: Array [], + }, + ModuleScope$2 { + block: Program$3, + isStrict: true, + references: Array [ + Reference$1, + ], + set: Map { + "foo" => Variable$1, + "T" => Variable$2, + }, + type: "module", + upper: GlobalScope$1, + variables: Array [ + Variable$1, + Variable$2, + ], + }, + ], +} +`; diff --git a/packages/scope-manager/tests/fixtures/import/type-default.ts.shot b/packages/scope-manager/tests/fixtures/import/type-default.ts.shot index 4f84aa209020..85b9df61e067 100644 --- a/packages/scope-manager/tests/fixtures/import/type-default.ts.shot +++ b/packages/scope-manager/tests/fixtures/import/type-default.ts.shot @@ -20,8 +20,16 @@ ScopeManager { isWrite: false, resolved: Variable$1, }, + Reference$3 { + identifier: Identifier<"T">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$1, + }, ], - isValueVariable: false, + isValueVariable: true, isTypeVariable: true, }, Variable$2 { @@ -76,14 +84,7 @@ ScopeManager { references: Array [ Reference$1, Reference$2, - Reference$3 { - identifier: Identifier<"T">, - isRead: true, - isTypeReference: false, - isValueReference: true, - isWrite: false, - resolved: null, - }, + Reference$3, ], set: Map { "T" => Variable$1, diff --git a/packages/scope-manager/tests/fixtures/import/type-named-value.ts b/packages/scope-manager/tests/fixtures/import/type-named-value.ts new file mode 100644 index 000000000000..112f86af9e6e --- /dev/null +++ b/packages/scope-manager/tests/fixtures/import/type-named-value.ts @@ -0,0 +1,5 @@ +//// @sourceType = module + +import type { foo } from 'foo'; + +type T = typeof foo; diff --git a/packages/scope-manager/tests/fixtures/import/type-named-value.ts.shot b/packages/scope-manager/tests/fixtures/import/type-named-value.ts.shot new file mode 100644 index 000000000000..36fa441cea15 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/import/type-named-value.ts.shot @@ -0,0 +1,69 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`import type-named-value 1`] = ` +ScopeManager { + variables: Array [ + Variable$1 { + defs: Array [ + ImportBindingDefinition$1 { + name: Identifier<"foo">, + node: ImportSpecifier$1, + }, + ], + name: "foo", + references: Array [ + Reference$1 { + identifier: Identifier<"foo">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$1, + }, + ], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$2 { + defs: Array [ + TypeDefinition$2 { + name: Identifier<"T">, + node: TSTypeAliasDeclaration$2, + }, + ], + name: "T", + references: Array [], + isValueVariable: false, + isTypeVariable: true, + }, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$3, + isStrict: false, + references: Array [], + set: Map {}, + type: "global", + upper: null, + variables: Array [], + }, + ModuleScope$2 { + block: Program$3, + isStrict: true, + references: Array [ + Reference$1, + ], + set: Map { + "foo" => Variable$1, + "T" => Variable$2, + }, + type: "module", + upper: GlobalScope$1, + variables: Array [ + Variable$1, + Variable$2, + ], + }, + ], +} +`; diff --git a/packages/scope-manager/tests/fixtures/import/type-named.ts.shot b/packages/scope-manager/tests/fixtures/import/type-named.ts.shot index 359026e7d454..6e7a2481f795 100644 --- a/packages/scope-manager/tests/fixtures/import/type-named.ts.shot +++ b/packages/scope-manager/tests/fixtures/import/type-named.ts.shot @@ -20,8 +20,16 @@ ScopeManager { isWrite: false, resolved: Variable$1, }, + Reference$3 { + identifier: Identifier<"T">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$1, + }, ], - isValueVariable: false, + isValueVariable: true, isTypeVariable: true, }, Variable$2 { @@ -76,14 +84,7 @@ ScopeManager { references: Array [ Reference$1, Reference$2, - Reference$3 { - identifier: Identifier<"T">, - isRead: true, - isTypeReference: false, - isValueReference: true, - isWrite: false, - resolved: null, - }, + Reference$3, ], set: Map { "T" => Variable$1,