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