Skip to content

Commit 75f88ee

Browse files
authored
Do not short-circuit module visibility calculation when alias visibility is requested (microsoft#36339)
1 parent eac2180 commit 75f88ee

5 files changed

+162
-0
lines changed

src/compiler/checker.ts

+15
Original file line numberDiff line numberDiff line change
@@ -3569,6 +3569,7 @@ namespace ts {
35693569
if (!length(symbols)) return;
35703570

35713571
let hadAccessibleChain: Symbol | undefined;
3572+
let earlyModuleBail = false;
35723573
for (const symbol of symbols!) {
35733574
// Symbol is accessible if it by itself is accessible
35743575
const accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/ false);
@@ -3581,6 +3582,14 @@ namespace ts {
35813582
}
35823583
else {
35833584
if (some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
3585+
if (shouldComputeAliasesToMakeVisible) {
3586+
earlyModuleBail = true;
3587+
// Generally speaking, we want to use the aliases that already exist to refer to a module, if present
3588+
// In order to do so, we need to find those aliases in order to retain them in declaration emit; so
3589+
// if we are in declaration emit, we cannot use the fast path for module visibility until we've exhausted
3590+
// all other visibility options (in order to capture the possible aliases used to reference the module)
3591+
continue;
3592+
}
35843593
// Any meaning of a module symbol is always accessible via an `import` type
35853594
return {
35863595
accessibility: SymbolAccessibility.Accessible
@@ -3617,6 +3626,12 @@ namespace ts {
36173626
}
36183627
}
36193628

3629+
if (earlyModuleBail) {
3630+
return {
3631+
accessibility: SymbolAccessibility.Accessible
3632+
};
3633+
}
3634+
36203635
if (hadAccessibleChain) {
36213636
return {
36223637
accessibility: SymbolAccessibility.NotAccessible,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//// [tests/cases/compiler/declarationsIndirectGeneratedAliasReference.ts] ////
2+
3+
//// [ctor.d.ts]
4+
export interface Ctor {
5+
x: number;
6+
}
7+
export type ExtendedCtor<T> = {x: number, ext: T};
8+
export interface CtorConstructor {
9+
extends<T>(x: T): ExtendedCtor<T extends unknown ? Ctor : undefined>;
10+
}
11+
export const Ctor: CtorConstructor;
12+
//// [index.d.ts]
13+
import { Ctor } from "./ctor";
14+
export default Ctor;
15+
//// [index.ts]
16+
import * as ns from "mod";
17+
const Ctor = ns.default;
18+
export const MyComp = Ctor.extends({foo: "bar"});
19+
20+
21+
//// [index.js]
22+
"use strict";
23+
exports.__esModule = true;
24+
var ns = require("mod");
25+
var Ctor = ns["default"];
26+
exports.MyComp = Ctor["extends"]({ foo: "bar" });
27+
28+
29+
//// [index.d.ts]
30+
import * as ns from "mod";
31+
export declare const MyComp: import("mod/ctor").ExtendedCtor<ns.default>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
=== tests/cases/compiler/node_modules/mod/ctor.d.ts ===
2+
export interface Ctor {
3+
>Ctor : Symbol(Ctor, Decl(ctor.d.ts, 0, 0), Decl(ctor.d.ts, 7, 12))
4+
5+
x: number;
6+
>x : Symbol(Ctor.x, Decl(ctor.d.ts, 0, 23))
7+
}
8+
export type ExtendedCtor<T> = {x: number, ext: T};
9+
>ExtendedCtor : Symbol(ExtendedCtor, Decl(ctor.d.ts, 2, 1))
10+
>T : Symbol(T, Decl(ctor.d.ts, 3, 25))
11+
>x : Symbol(x, Decl(ctor.d.ts, 3, 31))
12+
>ext : Symbol(ext, Decl(ctor.d.ts, 3, 41))
13+
>T : Symbol(T, Decl(ctor.d.ts, 3, 25))
14+
15+
export interface CtorConstructor {
16+
>CtorConstructor : Symbol(CtorConstructor, Decl(ctor.d.ts, 3, 50))
17+
18+
extends<T>(x: T): ExtendedCtor<T extends unknown ? Ctor : undefined>;
19+
>extends : Symbol(CtorConstructor.extends, Decl(ctor.d.ts, 4, 34))
20+
>T : Symbol(T, Decl(ctor.d.ts, 5, 12))
21+
>x : Symbol(x, Decl(ctor.d.ts, 5, 15))
22+
>T : Symbol(T, Decl(ctor.d.ts, 5, 12))
23+
>ExtendedCtor : Symbol(ExtendedCtor, Decl(ctor.d.ts, 2, 1))
24+
>T : Symbol(T, Decl(ctor.d.ts, 5, 12))
25+
>Ctor : Symbol(Ctor, Decl(ctor.d.ts, 0, 0), Decl(ctor.d.ts, 7, 12))
26+
}
27+
export const Ctor: CtorConstructor;
28+
>Ctor : Symbol(Ctor, Decl(ctor.d.ts, 0, 0), Decl(ctor.d.ts, 7, 12))
29+
>CtorConstructor : Symbol(CtorConstructor, Decl(ctor.d.ts, 3, 50))
30+
31+
=== tests/cases/compiler/node_modules/mod/index.d.ts ===
32+
import { Ctor } from "./ctor";
33+
>Ctor : Symbol(Ctor, Decl(index.d.ts, 0, 8))
34+
35+
export default Ctor;
36+
>Ctor : Symbol(Ctor, Decl(index.d.ts, 0, 8))
37+
38+
=== tests/cases/compiler/index.ts ===
39+
import * as ns from "mod";
40+
>ns : Symbol(ns, Decl(index.ts, 0, 6))
41+
42+
const Ctor = ns.default;
43+
>Ctor : Symbol(Ctor, Decl(index.ts, 1, 5))
44+
>ns.default : Symbol(ns.default, Decl(index.d.ts, 0, 30))
45+
>ns : Symbol(ns, Decl(index.ts, 0, 6))
46+
>default : Symbol(ns.default, Decl(index.d.ts, 0, 30))
47+
48+
export const MyComp = Ctor.extends({foo: "bar"});
49+
>MyComp : Symbol(MyComp, Decl(index.ts, 2, 12))
50+
>Ctor.extends : Symbol(CtorConstructor.extends, Decl(ctor.d.ts, 4, 34))
51+
>Ctor : Symbol(Ctor, Decl(index.ts, 1, 5))
52+
>extends : Symbol(CtorConstructor.extends, Decl(ctor.d.ts, 4, 34))
53+
>foo : Symbol(foo, Decl(index.ts, 2, 36))
54+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
=== tests/cases/compiler/node_modules/mod/ctor.d.ts ===
2+
export interface Ctor {
3+
x: number;
4+
>x : number
5+
}
6+
export type ExtendedCtor<T> = {x: number, ext: T};
7+
>ExtendedCtor : ExtendedCtor<T>
8+
>x : number
9+
>ext : T
10+
11+
export interface CtorConstructor {
12+
extends<T>(x: T): ExtendedCtor<T extends unknown ? Ctor : undefined>;
13+
>extends : <T>(x: T) => ExtendedCtor<T extends unknown ? Ctor : undefined>
14+
>x : T
15+
}
16+
export const Ctor: CtorConstructor;
17+
>Ctor : CtorConstructor
18+
19+
=== tests/cases/compiler/node_modules/mod/index.d.ts ===
20+
import { Ctor } from "./ctor";
21+
>Ctor : import("tests/cases/compiler/node_modules/mod/ctor").CtorConstructor
22+
23+
export default Ctor;
24+
>Ctor : Ctor
25+
26+
=== tests/cases/compiler/index.ts ===
27+
import * as ns from "mod";
28+
>ns : typeof ns
29+
30+
const Ctor = ns.default;
31+
>Ctor : import("tests/cases/compiler/node_modules/mod/ctor").CtorConstructor
32+
>ns.default : import("tests/cases/compiler/node_modules/mod/ctor").CtorConstructor
33+
>ns : typeof ns
34+
>default : import("tests/cases/compiler/node_modules/mod/ctor").CtorConstructor
35+
36+
export const MyComp = Ctor.extends({foo: "bar"});
37+
>MyComp : import("tests/cases/compiler/node_modules/mod/ctor").ExtendedCtor<import("tests/cases/compiler/node_modules/mod/ctor").Ctor>
38+
>Ctor.extends({foo: "bar"}) : import("tests/cases/compiler/node_modules/mod/ctor").ExtendedCtor<import("tests/cases/compiler/node_modules/mod/ctor").Ctor>
39+
>Ctor.extends : <T>(x: T) => import("tests/cases/compiler/node_modules/mod/ctor").ExtendedCtor<T extends unknown ? import("tests/cases/compiler/node_modules/mod/ctor").Ctor : undefined>
40+
>Ctor : import("tests/cases/compiler/node_modules/mod/ctor").CtorConstructor
41+
>extends : <T>(x: T) => import("tests/cases/compiler/node_modules/mod/ctor").ExtendedCtor<T extends unknown ? import("tests/cases/compiler/node_modules/mod/ctor").Ctor : undefined>
42+
>{foo: "bar"} : { foo: string; }
43+
>foo : string
44+
>"bar" : "bar"
45+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// @declaration: true
2+
// @filename: node_modules/mod/ctor.d.ts
3+
export interface Ctor {
4+
x: number;
5+
}
6+
export type ExtendedCtor<T> = {x: number, ext: T};
7+
export interface CtorConstructor {
8+
extends<T>(x: T): ExtendedCtor<T extends unknown ? Ctor : undefined>;
9+
}
10+
export const Ctor: CtorConstructor;
11+
// @filename: node_modules/mod/index.d.ts
12+
import { Ctor } from "./ctor";
13+
export default Ctor;
14+
// @filename: index.ts
15+
import * as ns from "mod";
16+
const Ctor = ns.default;
17+
export const MyComp = Ctor.extends({foo: "bar"});

0 commit comments

Comments
 (0)