Skip to content

Commit 916e95a

Browse files
authored
fix(scope-manager): treat type imports as both values and types (typescript-eslint#2494)
Fixes typescript-eslint#2453
1 parent a40f54c commit 916e95a

File tree

9 files changed

+174
-37
lines changed

9 files changed

+174
-37
lines changed

packages/eslint-plugin/tests/rules/no-unused-vars.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,11 @@ type StyledPaymentProps = {
783783
784784
export const StyledPayment = styled.div<StyledPaymentProps>\`\`;
785785
`,
786+
// https://github.com/typescript-eslint/typescript-eslint/issues/2453
787+
`
788+
import type { foo } from './a';
789+
export type Bar = typeof foo;
790+
`,
786791
],
787792

788793
invalid: [

packages/scope-manager/src/definition/ImportBindingDefinition.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,10 @@ class ImportBindingDefinition extends DefinitionBase<
3030
decl: TSESTree.ImportDeclaration | TSESTree.TSImportEqualsDeclaration,
3131
) {
3232
super(DefinitionType.ImportBinding, name, node, decl);
33-
if ('importKind' in this.parent && this.parent.importKind === 'type') {
34-
this.isVariableDefinition = false;
35-
} else {
36-
this.isVariableDefinition = true;
37-
}
3833
}
3934

4035
public readonly isTypeDefinition = true;
41-
public readonly isVariableDefinition: boolean;
36+
public readonly isVariableDefinition = true;
4237
}
4338

4439
export { ImportBindingDefinition };
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//// @sourceType = module
2+
3+
import type foo from 'foo';
4+
5+
type T = typeof foo;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`import type-default-value 1`] = `
4+
ScopeManager {
5+
variables: Array [
6+
Variable$1 {
7+
defs: Array [
8+
ImportBindingDefinition$1 {
9+
name: Identifier<"foo">,
10+
node: ImportDefaultSpecifier$1,
11+
},
12+
],
13+
name: "foo",
14+
references: Array [
15+
Reference$1 {
16+
identifier: Identifier<"foo">,
17+
isRead: true,
18+
isTypeReference: false,
19+
isValueReference: true,
20+
isWrite: false,
21+
resolved: Variable$1,
22+
},
23+
],
24+
isValueVariable: true,
25+
isTypeVariable: true,
26+
},
27+
Variable$2 {
28+
defs: Array [
29+
TypeDefinition$2 {
30+
name: Identifier<"T">,
31+
node: TSTypeAliasDeclaration$2,
32+
},
33+
],
34+
name: "T",
35+
references: Array [],
36+
isValueVariable: false,
37+
isTypeVariable: true,
38+
},
39+
],
40+
scopes: Array [
41+
GlobalScope$1 {
42+
block: Program$3,
43+
isStrict: false,
44+
references: Array [],
45+
set: Map {},
46+
type: "global",
47+
upper: null,
48+
variables: Array [],
49+
},
50+
ModuleScope$2 {
51+
block: Program$3,
52+
isStrict: true,
53+
references: Array [
54+
Reference$1,
55+
],
56+
set: Map {
57+
"foo" => Variable$1,
58+
"T" => Variable$2,
59+
},
60+
type: "module",
61+
upper: GlobalScope$1,
62+
variables: Array [
63+
Variable$1,
64+
Variable$2,
65+
],
66+
},
67+
],
68+
}
69+
`;

packages/scope-manager/tests/fixtures/import/type-default.ts.shot

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,16 @@ ScopeManager {
2020
isWrite: false,
2121
resolved: Variable$1,
2222
},
23+
Reference$3 {
24+
identifier: Identifier<"T">,
25+
isRead: true,
26+
isTypeReference: false,
27+
isValueReference: true,
28+
isWrite: false,
29+
resolved: Variable$1,
30+
},
2331
],
24-
isValueVariable: false,
32+
isValueVariable: true,
2533
isTypeVariable: true,
2634
},
2735
Variable$2 {
@@ -76,14 +84,7 @@ ScopeManager {
7684
references: Array [
7785
Reference$1,
7886
Reference$2,
79-
Reference$3 {
80-
identifier: Identifier<"T">,
81-
isRead: true,
82-
isTypeReference: false,
83-
isValueReference: true,
84-
isWrite: false,
85-
resolved: null,
86-
},
87+
Reference$3,
8788
],
8889
set: Map {
8990
"T" => Variable$1,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//// @sourceType = module
2+
3+
import type { foo } from 'foo';
4+
5+
type T = typeof foo;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`import type-named-value 1`] = `
4+
ScopeManager {
5+
variables: Array [
6+
Variable$1 {
7+
defs: Array [
8+
ImportBindingDefinition$1 {
9+
name: Identifier<"foo">,
10+
node: ImportSpecifier$1,
11+
},
12+
],
13+
name: "foo",
14+
references: Array [
15+
Reference$1 {
16+
identifier: Identifier<"foo">,
17+
isRead: true,
18+
isTypeReference: false,
19+
isValueReference: true,
20+
isWrite: false,
21+
resolved: Variable$1,
22+
},
23+
],
24+
isValueVariable: true,
25+
isTypeVariable: true,
26+
},
27+
Variable$2 {
28+
defs: Array [
29+
TypeDefinition$2 {
30+
name: Identifier<"T">,
31+
node: TSTypeAliasDeclaration$2,
32+
},
33+
],
34+
name: "T",
35+
references: Array [],
36+
isValueVariable: false,
37+
isTypeVariable: true,
38+
},
39+
],
40+
scopes: Array [
41+
GlobalScope$1 {
42+
block: Program$3,
43+
isStrict: false,
44+
references: Array [],
45+
set: Map {},
46+
type: "global",
47+
upper: null,
48+
variables: Array [],
49+
},
50+
ModuleScope$2 {
51+
block: Program$3,
52+
isStrict: true,
53+
references: Array [
54+
Reference$1,
55+
],
56+
set: Map {
57+
"foo" => Variable$1,
58+
"T" => Variable$2,
59+
},
60+
type: "module",
61+
upper: GlobalScope$1,
62+
variables: Array [
63+
Variable$1,
64+
Variable$2,
65+
],
66+
},
67+
],
68+
}
69+
`;

packages/scope-manager/tests/fixtures/import/type-named.ts.shot

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,16 @@ ScopeManager {
2020
isWrite: false,
2121
resolved: Variable$1,
2222
},
23+
Reference$3 {
24+
identifier: Identifier<"T">,
25+
isRead: true,
26+
isTypeReference: false,
27+
isValueReference: true,
28+
isWrite: false,
29+
resolved: Variable$1,
30+
},
2331
],
24-
isValueVariable: false,
32+
isValueVariable: true,
2533
isTypeVariable: true,
2634
},
2735
Variable$2 {
@@ -76,14 +84,7 @@ ScopeManager {
7684
references: Array [
7785
Reference$1,
7886
Reference$2,
79-
Reference$3 {
80-
identifier: Identifier<"T">,
81-
isRead: true,
82-
isTypeReference: false,
83-
isValueReference: true,
84-
isWrite: false,
85-
resolved: null,
86-
},
87+
Reference$3,
8788
],
8889
set: Map {
8990
"T" => Variable$1,

packages/scope-manager/tests/types/reference-type.test.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -180,17 +180,4 @@ describe('referencing a type - negative', () => {
180180
const variable = scopeManager.getDeclaredVariables(node)[0];
181181
expect(variable.references).toHaveLength(0);
182182
});
183-
184-
it('does not record a reference when a type import is referenced from a value', () => {
185-
const { ast, scopeManager } = parseAndAnalyze(
186-
`
187-
import type { foo } from 'module';
188-
const test = foo;
189-
`,
190-
'module',
191-
);
192-
const node = getSpecificNode(ast, AST_NODE_TYPES.ImportSpecifier);
193-
const variable = scopeManager.getDeclaredVariables(node)[0];
194-
expect(variable.references).toHaveLength(0);
195-
});
196183
});

0 commit comments

Comments
 (0)