Skip to content

Commit ab31628

Browse files
committed
Type-only namespace imports
1 parent acbee11 commit ab31628

File tree

6 files changed

+182
-1
lines changed

6 files changed

+182
-1
lines changed

src/compiler/checker.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -2227,7 +2227,8 @@ namespace ts {
22272227

22282228
function getTargetOfNamespaceImport(node: NamespaceImport, dontResolveAlias: boolean): Symbol | undefined {
22292229
const moduleSpecifier = node.parent.parent.moduleSpecifier;
2230-
return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
2230+
const moduleSymbol = resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
2231+
return moduleSymbol && node.parent.isTypeOnly ? createTypeOnlySymbol(moduleSymbol) : moduleSymbol;
22312232
}
22322233

22332234
// This function creates a synthetic symbol that combines the value side of one symbol with the
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/b.ts(2,1): error TS2708: Cannot use namespace 'types' as a value.
2+
/b.ts(3,1): error TS2708: Cannot use namespace 'types' as a value.
3+
/b.ts(4,14): error TS2694: Namespace '"/a"' has no exported member 'Value'.
4+
/b.ts(5,7): error TS2741: Property 'a' is missing in type '{}' but required in type 'A'.
5+
/b.ts(6,7): error TS2741: Property 'b' is missing in type '{}' but required in type 'B'.
6+
7+
8+
==== /a.ts (0 errors) ====
9+
export class A { a!: string }
10+
export class B { b!: number }
11+
export type C<T> = T;
12+
export const Value = {};
13+
14+
==== /b.ts (5 errors) ====
15+
import type * as types from './a';
16+
types;
17+
~~~~~
18+
!!! error TS2708: Cannot use namespace 'types' as a value.
19+
types.Value;
20+
~~~~~
21+
!!! error TS2708: Cannot use namespace 'types' as a value.
22+
let v: types.Value;
23+
~~~~~
24+
!!! error TS2694: Namespace '"/a"' has no exported member 'Value'.
25+
const a: types.A = {};
26+
~
27+
!!! error TS2741: Property 'a' is missing in type '{}' but required in type 'A'.
28+
!!! related TS2728 /a.ts:1:18: 'a' is declared here.
29+
const b: types.B = {};
30+
~
31+
!!! error TS2741: Property 'b' is missing in type '{}' but required in type 'B'.
32+
!!! related TS2728 /a.ts:2:18: 'b' is declared here.
33+
const c: types.C<string> = "";
34+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//// [tests/cases/conformance/externalModules/typeOnly/importClause_namespaceImport.ts] ////
2+
3+
//// [a.ts]
4+
export class A { a!: string }
5+
export class B { b!: number }
6+
export type C<T> = T;
7+
export const Value = {};
8+
9+
//// [b.ts]
10+
import type * as types from './a';
11+
types;
12+
types.Value;
13+
let v: types.Value;
14+
const a: types.A = {};
15+
const b: types.B = {};
16+
const c: types.C<string> = "";
17+
18+
19+
//// [a.js]
20+
"use strict";
21+
exports.__esModule = true;
22+
var A = /** @class */ (function () {
23+
function A() {
24+
}
25+
return A;
26+
}());
27+
exports.A = A;
28+
var B = /** @class */ (function () {
29+
function B() {
30+
}
31+
return B;
32+
}());
33+
exports.B = B;
34+
exports.Value = {};
35+
//// [b.js]
36+
"use strict";
37+
exports.__esModule = true;
38+
types;
39+
types.Value;
40+
var v;
41+
var a = {};
42+
var b = {};
43+
var c = "";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
=== /a.ts ===
2+
export class A { a!: string }
3+
>A : Symbol(A, Decl(a.ts, 0, 0))
4+
>a : Symbol(A.a, Decl(a.ts, 0, 16))
5+
6+
export class B { b!: number }
7+
>B : Symbol(B, Decl(a.ts, 0, 29))
8+
>b : Symbol(B.b, Decl(a.ts, 1, 16))
9+
10+
export type C<T> = T;
11+
>C : Symbol(C, Decl(a.ts, 1, 29))
12+
>T : Symbol(T, Decl(a.ts, 2, 14))
13+
>T : Symbol(T, Decl(a.ts, 2, 14))
14+
15+
export const Value = {};
16+
>Value : Symbol(Value, Decl(a.ts, 3, 12))
17+
18+
=== /b.ts ===
19+
import type * as types from './a';
20+
>types : Symbol(types, Decl(b.ts, 0, 11))
21+
22+
types;
23+
types.Value;
24+
let v: types.Value;
25+
>v : Symbol(v, Decl(b.ts, 3, 3))
26+
>types : Symbol(types, Decl(b.ts, 0, 11))
27+
28+
const a: types.A = {};
29+
>a : Symbol(a, Decl(b.ts, 4, 5))
30+
>types : Symbol(types, Decl(b.ts, 0, 11))
31+
>A : Symbol(types.A)
32+
33+
const b: types.B = {};
34+
>b : Symbol(b, Decl(b.ts, 5, 5))
35+
>types : Symbol(types, Decl(b.ts, 0, 11))
36+
>B : Symbol(types.B)
37+
38+
const c: types.C<string> = "";
39+
>c : Symbol(c, Decl(b.ts, 6, 5))
40+
>types : Symbol(types, Decl(b.ts, 0, 11))
41+
>C : Symbol(types.C, Decl(a.ts, 1, 29))
42+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
=== /a.ts ===
2+
export class A { a!: string }
3+
>A : A
4+
>a : string
5+
6+
export class B { b!: number }
7+
>B : B
8+
>b : number
9+
10+
export type C<T> = T;
11+
>C : T
12+
13+
export const Value = {};
14+
>Value : {}
15+
>{} : {}
16+
17+
=== /b.ts ===
18+
import type * as types from './a';
19+
>types : any
20+
21+
types;
22+
>types : any
23+
24+
types.Value;
25+
>types.Value : any
26+
>types : any
27+
>Value : any
28+
29+
let v: types.Value;
30+
>v : any
31+
>types : any
32+
33+
const a: types.A = {};
34+
>a : import("/a").A
35+
>types : any
36+
>{} : {}
37+
38+
const b: types.B = {};
39+
>b : import("/a").B
40+
>types : any
41+
>{} : {}
42+
43+
const c: types.C<string> = "";
44+
>c : string
45+
>types : any
46+
>"" : ""
47+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @Filename: /a.ts
2+
export class A { a!: string }
3+
export class B { b!: number }
4+
export type C<T> = T;
5+
export const Value = {};
6+
7+
// @Filename: /b.ts
8+
import type * as types from './a';
9+
types;
10+
types.Value;
11+
let v: types.Value;
12+
const a: types.A = {};
13+
const b: types.B = {};
14+
const c: types.C<string> = "";

0 commit comments

Comments
 (0)