diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a6e33b763c3..52cd728e7f7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3569,6 +3569,7 @@ namespace ts { if (!length(symbols)) return; let hadAccessibleChain: Symbol | undefined; + let earlyModuleBail = false; for (const symbol of symbols!) { // Symbol is accessible if it by itself is accessible const accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/ false); @@ -3581,6 +3582,14 @@ namespace ts { } else { if (some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) { + if (shouldComputeAliasesToMakeVisible) { + earlyModuleBail = true; + // Generally speaking, we want to use the aliases that already exist to refer to a module, if present + // In order to do so, we need to find those aliases in order to retain them in declaration emit; so + // if we are in declaration emit, we cannot use the fast path for module visibility until we've exhausted + // all other visibility options (in order to capture the possible aliases used to reference the module) + continue; + } // Any meaning of a module symbol is always accessible via an `import` type return { accessibility: SymbolAccessibility.Accessible @@ -3617,6 +3626,12 @@ namespace ts { } } + if (earlyModuleBail) { + return { + accessibility: SymbolAccessibility.Accessible + }; + } + if (hadAccessibleChain) { return { accessibility: SymbolAccessibility.NotAccessible, diff --git a/tests/baselines/reference/declarationsIndirectGeneratedAliasReference.js b/tests/baselines/reference/declarationsIndirectGeneratedAliasReference.js new file mode 100644 index 00000000000..74d040697a2 --- /dev/null +++ b/tests/baselines/reference/declarationsIndirectGeneratedAliasReference.js @@ -0,0 +1,31 @@ +//// [tests/cases/compiler/declarationsIndirectGeneratedAliasReference.ts] //// + +//// [ctor.d.ts] +export interface Ctor { + x: number; +} +export type ExtendedCtor = {x: number, ext: T}; +export interface CtorConstructor { + extends(x: T): ExtendedCtor; +} +export const Ctor: CtorConstructor; +//// [index.d.ts] +import { Ctor } from "./ctor"; +export default Ctor; +//// [index.ts] +import * as ns from "mod"; +const Ctor = ns.default; +export const MyComp = Ctor.extends({foo: "bar"}); + + +//// [index.js] +"use strict"; +exports.__esModule = true; +var ns = require("mod"); +var Ctor = ns["default"]; +exports.MyComp = Ctor["extends"]({ foo: "bar" }); + + +//// [index.d.ts] +import * as ns from "mod"; +export declare const MyComp: import("mod/ctor").ExtendedCtor; diff --git a/tests/baselines/reference/declarationsIndirectGeneratedAliasReference.symbols b/tests/baselines/reference/declarationsIndirectGeneratedAliasReference.symbols new file mode 100644 index 00000000000..f09bdc55a78 --- /dev/null +++ b/tests/baselines/reference/declarationsIndirectGeneratedAliasReference.symbols @@ -0,0 +1,54 @@ +=== tests/cases/compiler/node_modules/mod/ctor.d.ts === +export interface Ctor { +>Ctor : Symbol(Ctor, Decl(ctor.d.ts, 0, 0), Decl(ctor.d.ts, 7, 12)) + + x: number; +>x : Symbol(Ctor.x, Decl(ctor.d.ts, 0, 23)) +} +export type ExtendedCtor = {x: number, ext: T}; +>ExtendedCtor : Symbol(ExtendedCtor, Decl(ctor.d.ts, 2, 1)) +>T : Symbol(T, Decl(ctor.d.ts, 3, 25)) +>x : Symbol(x, Decl(ctor.d.ts, 3, 31)) +>ext : Symbol(ext, Decl(ctor.d.ts, 3, 41)) +>T : Symbol(T, Decl(ctor.d.ts, 3, 25)) + +export interface CtorConstructor { +>CtorConstructor : Symbol(CtorConstructor, Decl(ctor.d.ts, 3, 50)) + + extends(x: T): ExtendedCtor; +>extends : Symbol(CtorConstructor.extends, Decl(ctor.d.ts, 4, 34)) +>T : Symbol(T, Decl(ctor.d.ts, 5, 12)) +>x : Symbol(x, Decl(ctor.d.ts, 5, 15)) +>T : Symbol(T, Decl(ctor.d.ts, 5, 12)) +>ExtendedCtor : Symbol(ExtendedCtor, Decl(ctor.d.ts, 2, 1)) +>T : Symbol(T, Decl(ctor.d.ts, 5, 12)) +>Ctor : Symbol(Ctor, Decl(ctor.d.ts, 0, 0), Decl(ctor.d.ts, 7, 12)) +} +export const Ctor: CtorConstructor; +>Ctor : Symbol(Ctor, Decl(ctor.d.ts, 0, 0), Decl(ctor.d.ts, 7, 12)) +>CtorConstructor : Symbol(CtorConstructor, Decl(ctor.d.ts, 3, 50)) + +=== tests/cases/compiler/node_modules/mod/index.d.ts === +import { Ctor } from "./ctor"; +>Ctor : Symbol(Ctor, Decl(index.d.ts, 0, 8)) + +export default Ctor; +>Ctor : Symbol(Ctor, Decl(index.d.ts, 0, 8)) + +=== tests/cases/compiler/index.ts === +import * as ns from "mod"; +>ns : Symbol(ns, Decl(index.ts, 0, 6)) + +const Ctor = ns.default; +>Ctor : Symbol(Ctor, Decl(index.ts, 1, 5)) +>ns.default : Symbol(ns.default, Decl(index.d.ts, 0, 30)) +>ns : Symbol(ns, Decl(index.ts, 0, 6)) +>default : Symbol(ns.default, Decl(index.d.ts, 0, 30)) + +export const MyComp = Ctor.extends({foo: "bar"}); +>MyComp : Symbol(MyComp, Decl(index.ts, 2, 12)) +>Ctor.extends : Symbol(CtorConstructor.extends, Decl(ctor.d.ts, 4, 34)) +>Ctor : Symbol(Ctor, Decl(index.ts, 1, 5)) +>extends : Symbol(CtorConstructor.extends, Decl(ctor.d.ts, 4, 34)) +>foo : Symbol(foo, Decl(index.ts, 2, 36)) + diff --git a/tests/baselines/reference/declarationsIndirectGeneratedAliasReference.types b/tests/baselines/reference/declarationsIndirectGeneratedAliasReference.types new file mode 100644 index 00000000000..fd5e2b65856 --- /dev/null +++ b/tests/baselines/reference/declarationsIndirectGeneratedAliasReference.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/node_modules/mod/ctor.d.ts === +export interface Ctor { + x: number; +>x : number +} +export type ExtendedCtor = {x: number, ext: T}; +>ExtendedCtor : ExtendedCtor +>x : number +>ext : T + +export interface CtorConstructor { + extends(x: T): ExtendedCtor; +>extends : (x: T) => ExtendedCtor +>x : T +} +export const Ctor: CtorConstructor; +>Ctor : CtorConstructor + +=== tests/cases/compiler/node_modules/mod/index.d.ts === +import { Ctor } from "./ctor"; +>Ctor : import("tests/cases/compiler/node_modules/mod/ctor").CtorConstructor + +export default Ctor; +>Ctor : Ctor + +=== tests/cases/compiler/index.ts === +import * as ns from "mod"; +>ns : typeof ns + +const Ctor = ns.default; +>Ctor : import("tests/cases/compiler/node_modules/mod/ctor").CtorConstructor +>ns.default : import("tests/cases/compiler/node_modules/mod/ctor").CtorConstructor +>ns : typeof ns +>default : import("tests/cases/compiler/node_modules/mod/ctor").CtorConstructor + +export const MyComp = Ctor.extends({foo: "bar"}); +>MyComp : import("tests/cases/compiler/node_modules/mod/ctor").ExtendedCtor +>Ctor.extends({foo: "bar"}) : import("tests/cases/compiler/node_modules/mod/ctor").ExtendedCtor +>Ctor.extends : (x: T) => import("tests/cases/compiler/node_modules/mod/ctor").ExtendedCtor +>Ctor : import("tests/cases/compiler/node_modules/mod/ctor").CtorConstructor +>extends : (x: T) => import("tests/cases/compiler/node_modules/mod/ctor").ExtendedCtor +>{foo: "bar"} : { foo: string; } +>foo : string +>"bar" : "bar" + diff --git a/tests/cases/compiler/declarationsIndirectGeneratedAliasReference.ts b/tests/cases/compiler/declarationsIndirectGeneratedAliasReference.ts new file mode 100644 index 00000000000..f669103187a --- /dev/null +++ b/tests/cases/compiler/declarationsIndirectGeneratedAliasReference.ts @@ -0,0 +1,17 @@ +// @declaration: true +// @filename: node_modules/mod/ctor.d.ts +export interface Ctor { + x: number; +} +export type ExtendedCtor = {x: number, ext: T}; +export interface CtorConstructor { + extends(x: T): ExtendedCtor; +} +export const Ctor: CtorConstructor; +// @filename: node_modules/mod/index.d.ts +import { Ctor } from "./ctor"; +export default Ctor; +// @filename: index.ts +import * as ns from "mod"; +const Ctor = ns.default; +export const MyComp = Ctor.extends({foo: "bar"});