• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts.projectSystem {
2    describe("unittests:: tsserver:: typeOnlyImportChains", () => {
3        it("named export -> type-only namespace import -> named export -> named import", () => {
4            const a = {
5                path: "/a.ts",
6                content: "export class A {}"
7            };
8            const b = {
9                path: "/b.ts",
10                content: "import type * as a from './a'; export { a };"
11            };
12            const c = {
13                path: "/c.ts",
14                content: "import { a } from './b'; new a.A();"
15            };
16
17            assertUsageError([a, b, c], c, Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type);
18        });
19
20        it("named export -> type-only named import -> named export -> named import", () => {
21            const a = {
22                path: "/a.ts",
23                content: "export class A {}"
24            };
25            const b = {
26                path: "/b.ts",
27                content: "import type { A } from './a'; export { A };"
28            };
29            const c = {
30                path: "/c.ts",
31                content: "import { A } from './b'; new A();"
32            };
33
34            assertUsageError([a, b, c], c, Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type);
35        });
36
37        it("named export -> type-only namespace import -> export equals -> import equals", () => {
38            const a = {
39                path: "/a.ts",
40                content: "export class A {}"
41            };
42            const b = {
43                path: "/b.ts",
44                content: "import type * as a from './a'; export = a;"
45            };
46            const c = {
47                path: "/c.ts",
48                content: "import a = require('./b'); new a.A();"
49            };
50
51            assertUsageError([a, b, c], c, Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type);
52        });
53
54        it("named export -> type-only namespace import -> export default -> import default", () => {
55            const a = {
56                path: "/a.ts",
57                content: "export class A {}"
58            };
59            const b = {
60                path: "/b.ts",
61                content: "import type * as a from './a'; export default a;"
62            };
63            const c = {
64                path: "/c.ts",
65                content: "import a from './b'; new a.A();"
66            };
67
68            assertUsageError([a, b, c], c, Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type);
69        });
70
71        it("export default -> type-only import default -> export default -> import default", () => {
72            const a = {
73                path: "/a.ts",
74                content: "export default class A {}"
75            };
76            const b = {
77                path: "/b.ts",
78                content: "import type A from './a'; export default A;"
79            };
80            const c = {
81                path: "/c.ts",
82                content: "import A from './b'; new A();"
83            };
84
85            assertUsageError([a, b, c], c, Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type);
86        });
87
88        it("named export -> type-only export from -> export star from -> named import", () => {
89            const a = {
90                path: "/a.ts",
91                content: "export class A {}"
92            };
93            const b = {
94                path: "/b.ts",
95                content: "export type { A } from './a';"
96            };
97            const c = {
98                path: "/c.ts",
99                content: "export * from './b';"
100            };
101            const d = {
102                path: "/d.ts",
103                content: "import { A } from './c'; new A();"
104            };
105
106            assertUsageError([a, b, c, d], d, Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type);
107        });
108
109        it("named export -> export namespace from -> type-only named import -> named export -> named import", () => {
110            const a = {
111                path: "/a.ts",
112                content: "export class A {}"
113            };
114            const b = {
115                path: "/b.ts",
116                content: "export * as a from './a';"
117            };
118            const c = {
119                path: "/c.ts",
120                content: "import type { a } from './b'; export { a };"
121            };
122            const d = {
123                path: "/d.ts",
124                content: "import { a } from './c'; new a.A();"
125            };
126
127            assertUsageError([a, b, c, d], d, Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type);
128        });
129
130        it("named export -> type-only export from -> export namespace from -> named import", () => {
131            const a = {
132                path: "/a.ts",
133                content: "export class A {}"
134            };
135            const b = {
136                path: "/b.ts",
137                content: "export type { A } from './a';"
138            };
139            const c = {
140                path: "/c.ts",
141                content: "export * as a from './b';"
142            };
143            const d = {
144                path: "/d.ts",
145                content: "import { a } from './c'; new a.A();"
146            };
147
148            assertUsageError([a, b, c, d], d, Diagnostics.Property_0_does_not_exist_on_type_1);
149        });
150    });
151
152    function assertUsageError(files: readonly TestFSWithWatch.File[], openFile: TestFSWithWatch.File, diagnostic: DiagnosticMessage) {
153        const host = createServerHost(files);
154        const session = createSession(host);
155        openFilesForSession([openFile], session);
156        const req = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
157            protocol.CommandTypes.SemanticDiagnosticsSync,
158            { file: openFile.path }
159        );
160        const diagnostics = session.executeCommand(req).response as protocol.Diagnostic[];
161        assert.lengthOf(diagnostics, 1);
162        assert.equal(diagnostics[0].code, diagnostic.code);
163    }
164}
165