Skip to content

Commit 033f9e0

Browse files
authored
Consider a symbol visible for declaration emit when it is the target of an ambient module's export= (microsoft#47835)
* Consider a symbol visible for declaration emit when it is the target of an ambient module's export= * Just use resolveExternalModuleSymbol
1 parent 7f022c5 commit 033f9e0

8 files changed

+226
-5
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3981,8 +3981,15 @@ namespace ts {
39813981
return res;
39823982
}
39833983
const candidates = mapDefined(symbol.declarations, d => {
3984-
if (!isAmbientModule(d) && d.parent && hasNonGlobalAugmentationExternalModuleSymbol(d.parent)) {
3985-
return getSymbolOfNode(d.parent);
3984+
if (!isAmbientModule(d) && d.parent){
3985+
// direct children of a module
3986+
if (hasNonGlobalAugmentationExternalModuleSymbol(d.parent)) {
3987+
return getSymbolOfNode(d.parent);
3988+
}
3989+
// export ='d member of an ambient module
3990+
if (isModuleBlock(d.parent) && d.parent.parent && resolveExternalModuleSymbol(getSymbolOfNode(d.parent.parent)) === symbol) {
3991+
return getSymbolOfNode(d.parent.parent);
3992+
}
39863993
}
39873994
if (isClassExpression(d) && isBinaryExpression(d.parent) && d.parent.operatorToken.kind === SyntaxKind.EqualsToken && isAccessExpression(d.parent.left) && isEntityNameExpression(d.parent.left.expression)) {
39883995
if (isModuleExportsAccessExpression(d.parent.left) || isExportsIdentifier(d.parent.left.expression)) {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//// [tests/cases/compiler/amdLikeInputDeclarationEmit.ts] ////
2+
3+
//// [typing.d.ts]
4+
declare function define<T=unknown>(name: string, modules: string[], ready: (...modules: unknown[]) => T);
5+
//// [BaseClass.d.ts]
6+
declare module "deps/BaseClass" {
7+
class BaseClass {
8+
static extends<A>(a: A): new () => A & BaseClass;
9+
}
10+
export = BaseClass;
11+
}
12+
//// [ExtendedClass.js]
13+
define("lib/ExtendedClass", ["deps/BaseClass"],
14+
/**
15+
* {typeof import("deps/BaseClass")}
16+
* @param {typeof import("deps/BaseClass")} BaseClass
17+
* @returns
18+
*/
19+
(BaseClass) => {
20+
21+
const ExtendedClass = BaseClass.extends({
22+
f: function() {
23+
return "something";
24+
}
25+
});
26+
27+
// Exports the module in a way tsc recognize class export
28+
const module = {};
29+
module.exports = ExtendedClass
30+
return module.exports;
31+
});
32+
33+
34+
35+
//// [ExtendedClass.d.ts]
36+
/// <reference path="../tests/cases/compiler/deps/BaseClass.d.ts" />
37+
export = ExtendedClass;
38+
declare const ExtendedClass: new () => {
39+
f: () => "something";
40+
} & import("deps/BaseClass");
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
=== tests/cases/compiler/typing.d.ts ===
2+
declare function define<T=unknown>(name: string, modules: string[], ready: (...modules: unknown[]) => T);
3+
>define : Symbol(define, Decl(typing.d.ts, 0, 0))
4+
>T : Symbol(T, Decl(typing.d.ts, 0, 24))
5+
>name : Symbol(name, Decl(typing.d.ts, 0, 35))
6+
>modules : Symbol(modules, Decl(typing.d.ts, 0, 48))
7+
>ready : Symbol(ready, Decl(typing.d.ts, 0, 67))
8+
>modules : Symbol(modules, Decl(typing.d.ts, 0, 76))
9+
>T : Symbol(T, Decl(typing.d.ts, 0, 24))
10+
11+
=== tests/cases/compiler/deps/BaseClass.d.ts ===
12+
declare module "deps/BaseClass" {
13+
>"deps/BaseClass" : Symbol("deps/BaseClass", Decl(BaseClass.d.ts, 0, 0))
14+
15+
class BaseClass {
16+
>BaseClass : Symbol(BaseClass, Decl(BaseClass.d.ts, 0, 33))
17+
18+
static extends<A>(a: A): new () => A & BaseClass;
19+
>extends : Symbol(BaseClass.extends, Decl(BaseClass.d.ts, 1, 21))
20+
>A : Symbol(A, Decl(BaseClass.d.ts, 2, 23))
21+
>a : Symbol(a, Decl(BaseClass.d.ts, 2, 26))
22+
>A : Symbol(A, Decl(BaseClass.d.ts, 2, 23))
23+
>A : Symbol(A, Decl(BaseClass.d.ts, 2, 23))
24+
>BaseClass : Symbol(BaseClass, Decl(BaseClass.d.ts, 0, 33))
25+
}
26+
export = BaseClass;
27+
>BaseClass : Symbol(BaseClass, Decl(BaseClass.d.ts, 0, 33))
28+
}
29+
=== tests/cases/compiler/ExtendedClass.js ===
30+
define("lib/ExtendedClass", ["deps/BaseClass"],
31+
>define : Symbol(define, Decl(typing.d.ts, 0, 0))
32+
33+
/**
34+
* {typeof import("deps/BaseClass")}
35+
* @param {typeof import("deps/BaseClass")} BaseClass
36+
* @returns
37+
*/
38+
(BaseClass) => {
39+
>BaseClass : Symbol(BaseClass, Decl(ExtendedClass.js, 6, 1))
40+
41+
const ExtendedClass = BaseClass.extends({
42+
>ExtendedClass : Symbol(ExtendedClass, Decl(ExtendedClass.js, 8, 9))
43+
>BaseClass.extends : Symbol(BaseClass.extends, Decl(BaseClass.d.ts, 1, 21))
44+
>BaseClass : Symbol(BaseClass, Decl(ExtendedClass.js, 6, 1))
45+
>extends : Symbol(BaseClass.extends, Decl(BaseClass.d.ts, 1, 21))
46+
47+
f: function() {
48+
>f : Symbol(f, Decl(ExtendedClass.js, 8, 45))
49+
50+
return "something";
51+
}
52+
});
53+
54+
// Exports the module in a way tsc recognize class export
55+
const module = {};
56+
>module : Symbol(module, Decl(ExtendedClass.js, 15, 9))
57+
58+
module.exports = ExtendedClass
59+
>module : Symbol(export=, Decl(ExtendedClass.js, 15, 22))
60+
>exports : Symbol(export=, Decl(ExtendedClass.js, 15, 22))
61+
>ExtendedClass : Symbol(ExtendedClass, Decl(ExtendedClass.js, 8, 9))
62+
63+
return module.exports;
64+
>module : Symbol(module, Decl(ExtendedClass.js, 15, 9))
65+
66+
});
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
=== tests/cases/compiler/typing.d.ts ===
2+
declare function define<T=unknown>(name: string, modules: string[], ready: (...modules: unknown[]) => T);
3+
>define : <T = unknown>(name: string, modules: string[], ready: (...modules: unknown[]) => T) => any
4+
>name : string
5+
>modules : string[]
6+
>ready : (...modules: unknown[]) => T
7+
>modules : unknown[]
8+
9+
=== tests/cases/compiler/deps/BaseClass.d.ts ===
10+
declare module "deps/BaseClass" {
11+
>"deps/BaseClass" : typeof import("deps/BaseClass")
12+
13+
class BaseClass {
14+
>BaseClass : BaseClass
15+
16+
static extends<A>(a: A): new () => A & BaseClass;
17+
>extends : <A>(a: A) => new () => A & BaseClass
18+
>a : A
19+
}
20+
export = BaseClass;
21+
>BaseClass : BaseClass
22+
}
23+
=== tests/cases/compiler/ExtendedClass.js ===
24+
define("lib/ExtendedClass", ["deps/BaseClass"],
25+
>define("lib/ExtendedClass", ["deps/BaseClass"], /** * {typeof import("deps/BaseClass")} * @param {typeof import("deps/BaseClass")} BaseClass * @returns */(BaseClass) => { const ExtendedClass = BaseClass.extends({ f: function() { return "something"; } }); // Exports the module in a way tsc recognize class export const module = {}; module.exports = ExtendedClass return module.exports;}) : any
26+
>define : <T = unknown>(name: string, modules: string[], ready: (...modules: unknown[]) => T) => any
27+
>"lib/ExtendedClass" : "lib/ExtendedClass"
28+
>["deps/BaseClass"] : string[]
29+
>"deps/BaseClass" : "deps/BaseClass"
30+
31+
/**
32+
* {typeof import("deps/BaseClass")}
33+
* @param {typeof import("deps/BaseClass")} BaseClass
34+
* @returns
35+
*/
36+
(BaseClass) => {
37+
>(BaseClass) => { const ExtendedClass = BaseClass.extends({ f: function() { return "something"; } }); // Exports the module in a way tsc recognize class export const module = {}; module.exports = ExtendedClass return module.exports;} : (BaseClass: typeof import("deps/BaseClass")) => any
38+
>BaseClass : typeof import("deps/BaseClass")
39+
40+
const ExtendedClass = BaseClass.extends({
41+
>ExtendedClass : new () => { f: () => "something"; } & import("deps/BaseClass")
42+
>BaseClass.extends({ f: function() { return "something"; } }) : new () => { f: () => "something"; } & import("deps/BaseClass")
43+
>BaseClass.extends : <A>(a: A) => new () => A & import("deps/BaseClass")
44+
>BaseClass : typeof import("deps/BaseClass")
45+
>extends : <A>(a: A) => new () => A & import("deps/BaseClass")
46+
>{ f: function() { return "something"; } } : { f: () => "something"; }
47+
48+
f: function() {
49+
>f : () => "something"
50+
>function() { return "something"; } : () => "something"
51+
52+
return "something";
53+
>"something" : "something"
54+
}
55+
});
56+
57+
// Exports the module in a way tsc recognize class export
58+
const module = {};
59+
>module : {}
60+
>{} : {}
61+
62+
module.exports = ExtendedClass
63+
>module.exports = ExtendedClass : any
64+
>module.exports : any
65+
>module : {}
66+
>exports : any
67+
>ExtendedClass : new () => { f: () => "something"; } & import("deps/BaseClass")
68+
69+
return module.exports;
70+
>module.exports : any
71+
>module : {}
72+
>exports : any
73+
74+
});

tests/baselines/reference/importDeclFromTypeNodeInJsSource.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ declare module "events" {
55
>"events" : typeof import("events")
66

77
namespace EventEmitter {
8-
>EventEmitter : typeof EventEmitter
8+
>EventEmitter : typeof import("events")
99

1010
class EventEmitter {
1111
>EventEmitter : EventEmitter

tests/baselines/reference/importTypeAmbient.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ declare module "foo" {
1313
>Point : Point
1414
}
1515
const x: import("foo") = { x: 0, y: 0 };
16-
>x : Point
16+
>x : import("foo")
1717
>{ x: 0, y: 0 } : { x: number; y: number; }
1818
>x : number
1919
>0 : 0

tests/baselines/reference/incompatibleExports1.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ declare module "baz" {
2323
}
2424

2525
module c {
26-
>c : typeof c
26+
>c : typeof import("baz")
2727

2828
export var c: string;
2929
>c : string
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// @declaration: true
2+
// @declarationDir: definitions
3+
// @emitDeclarationOnly: true
4+
// @checkJs: true
5+
// @allowJs: true
6+
// @filename: typing.d.ts
7+
declare function define<T=unknown>(name: string, modules: string[], ready: (...modules: unknown[]) => T);
8+
// @filename: deps/BaseClass.d.ts
9+
declare module "deps/BaseClass" {
10+
class BaseClass {
11+
static extends<A>(a: A): new () => A & BaseClass;
12+
}
13+
export = BaseClass;
14+
}
15+
// @filename: ExtendedClass.js
16+
define("lib/ExtendedClass", ["deps/BaseClass"],
17+
/**
18+
* {typeof import("deps/BaseClass")}
19+
* @param {typeof import("deps/BaseClass")} BaseClass
20+
* @returns
21+
*/
22+
(BaseClass) => {
23+
24+
const ExtendedClass = BaseClass.extends({
25+
f: function() {
26+
return "something";
27+
}
28+
});
29+
30+
// Exports the module in a way tsc recognize class export
31+
const module = {};
32+
module.exports = ExtendedClass
33+
return module.exports;
34+
});

0 commit comments

Comments
 (0)