mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 04:43:37 -05:00
Support augmenting module with export as namespace (#27281)
* Support augmenting module with `export as namespace` * Warn on use of merged symbol containing 'export as namespace'
This commit is contained in:
@@ -854,7 +854,7 @@ namespace ts {
|
||||
(source.flags | target.flags) & SymbolFlags.Assignment) {
|
||||
Debug.assert(source !== target);
|
||||
if (!(target.flags & SymbolFlags.Transient)) {
|
||||
target = cloneSymbol(target);
|
||||
target = cloneSymbol(resolveSymbol(target));
|
||||
}
|
||||
// Javascript static-property-assignment declarations always merge, even though they are also values
|
||||
if (source.flags & SymbolFlags.ValueModule && target.flags & SymbolFlags.ValueModule && target.constEnumOnlyModule && !source.constEnumOnlyModule) {
|
||||
@@ -883,7 +883,7 @@ namespace ts {
|
||||
else if (target.flags & SymbolFlags.NamespaceModule) {
|
||||
error(getNameOfDeclaration(source.declarations[0]), Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
|
||||
}
|
||||
else {
|
||||
else { // error
|
||||
const isEitherEnum = !!(target.flags & SymbolFlags.Enum || source.flags & SymbolFlags.Enum);
|
||||
const isEitherBlockScoped = !!(target.flags & SymbolFlags.BlockScopedVariable || source.flags & SymbolFlags.BlockScopedVariable);
|
||||
const message = isEitherEnum
|
||||
@@ -947,7 +947,8 @@ namespace ts {
|
||||
|
||||
function mergeSymbolTable(target: SymbolTable, source: SymbolTable) {
|
||||
source.forEach((sourceSymbol, id) => {
|
||||
target.set(id, target.has(id) ? mergeSymbol(target.get(id)!, sourceSymbol) : sourceSymbol);
|
||||
const targetSymbol = target.get(id);
|
||||
target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol) : sourceSymbol);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1549,8 +1550,7 @@ namespace ts {
|
||||
|
||||
// If we're in an external module, we can't reference value symbols created from UMD export declarations
|
||||
if (result && isInExternalModule && (meaning & SymbolFlags.Value) === SymbolFlags.Value && !(originalLocation!.flags & NodeFlags.JSDoc)) {
|
||||
const decls = result.declarations;
|
||||
if (decls && decls.length === 1 && decls[0].kind === SyntaxKind.NamespaceExportDeclaration) {
|
||||
if (some(result.declarations, d => isNamespaceExportDeclaration(d) || isSourceFile(d) && !!d.symbol.globalExports)) {
|
||||
error(errorLocation!, Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, unescapeLeadingUnderscores(name)); // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,10 @@ var z = 0;
|
||||
|
||||
=== tests/cases/compiler/duplicateVarsAcrossFileBoundaries_4.ts ===
|
||||
module P { }
|
||||
>P : Symbol(P, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 0), Decl(duplicateVarsAcrossFileBoundaries_5.ts, 2, 3))
|
||||
|
||||
import p = P;
|
||||
>p : Symbol(p, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 12), Decl(duplicateVarsAcrossFileBoundaries_5.ts, 2, 3))
|
||||
>p : Symbol(p, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 12))
|
||||
>P : Symbol(P, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 0))
|
||||
|
||||
var q;
|
||||
@@ -52,5 +52,5 @@ import q = Q;
|
||||
>Q : Symbol(Q, Decl(duplicateVarsAcrossFileBoundaries_5.ts, 0, 0))
|
||||
|
||||
var p;
|
||||
>p : Symbol(p, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 12), Decl(duplicateVarsAcrossFileBoundaries_5.ts, 2, 3))
|
||||
>p : Symbol(P, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 0), Decl(duplicateVarsAcrossFileBoundaries_5.ts, 2, 3))
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/a.d.ts(3,14): error TS2451: Cannot redeclare block-scoped variable 'conflict'.
|
||||
/b.ts(6,22): error TS2451: Cannot redeclare block-scoped variable 'conflict'.
|
||||
/b.ts(12,18): error TS2451: Cannot redeclare block-scoped variable 'conflict'.
|
||||
/b.ts(15,1): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
|
||||
/b.ts(15,7): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
|
||||
/b.ts(15,13): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
|
||||
/b.ts(15,19): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
|
||||
|
||||
|
||||
==== /a.d.ts (1 errors) ====
|
||||
export as namespace a;
|
||||
export const x = 0;
|
||||
export const conflict = 0;
|
||||
~~~~~~~~
|
||||
!!! error TS2451: Cannot redeclare block-scoped variable 'conflict'.
|
||||
!!! related TS6203 /b.ts:6:22: 'conflict' was also declared here.
|
||||
!!! related TS6204 /b.ts:6:22: and here.
|
||||
|
||||
==== /b.ts (6 errors) ====
|
||||
import * as a2 from "./a";
|
||||
|
||||
declare global {
|
||||
namespace a {
|
||||
export const y = 0;
|
||||
export const conflict = 0;
|
||||
~~~~~~~~
|
||||
!!! error TS2451: Cannot redeclare block-scoped variable 'conflict'.
|
||||
!!! related TS6203 /a.d.ts:3:14: 'conflict' was also declared here.
|
||||
}
|
||||
}
|
||||
|
||||
declare module "./a" {
|
||||
export const z = 0;
|
||||
export const conflict = 0;
|
||||
~~~~~~~~
|
||||
!!! error TS2451: Cannot redeclare block-scoped variable 'conflict'.
|
||||
!!! related TS6203 /a.d.ts:3:14: 'conflict' was also declared here.
|
||||
}
|
||||
|
||||
a.x + a.y + a.z + a.conflict;
|
||||
~
|
||||
!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
|
||||
~
|
||||
!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
|
||||
~
|
||||
!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
|
||||
~
|
||||
!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead.
|
||||
a2.x + a2.y + a2.z + a2.conflict;
|
||||
|
||||
32
tests/baselines/reference/exportAsNamespace_augment.js
Normal file
32
tests/baselines/reference/exportAsNamespace_augment.js
Normal file
@@ -0,0 +1,32 @@
|
||||
//// [tests/cases/compiler/exportAsNamespace_augment.ts] ////
|
||||
|
||||
//// [a.d.ts]
|
||||
export as namespace a;
|
||||
export const x = 0;
|
||||
export const conflict = 0;
|
||||
|
||||
//// [b.ts]
|
||||
import * as a2 from "./a";
|
||||
|
||||
declare global {
|
||||
namespace a {
|
||||
export const y = 0;
|
||||
export const conflict = 0;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "./a" {
|
||||
export const z = 0;
|
||||
export const conflict = 0;
|
||||
}
|
||||
|
||||
a.x + a.y + a.z + a.conflict;
|
||||
a2.x + a2.y + a2.z + a2.conflict;
|
||||
|
||||
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var a2 = require("./a");
|
||||
a.x + a.y + a.z + a.conflict;
|
||||
a2.x + a2.y + a2.z + a2.conflict;
|
||||
66
tests/baselines/reference/exportAsNamespace_augment.symbols
Normal file
66
tests/baselines/reference/exportAsNamespace_augment.symbols
Normal file
@@ -0,0 +1,66 @@
|
||||
=== /a.d.ts ===
|
||||
export as namespace a;
|
||||
>a : Symbol(a, Decl(a.d.ts, 0, 0))
|
||||
|
||||
export const x = 0;
|
||||
>x : Symbol(x, Decl(a.d.ts, 1, 12))
|
||||
|
||||
export const conflict = 0;
|
||||
>conflict : Symbol(conflict, Decl(a.d.ts, 2, 12))
|
||||
|
||||
=== /b.ts ===
|
||||
import * as a2 from "./a";
|
||||
>a2 : Symbol(a2, Decl(b.ts, 0, 6))
|
||||
|
||||
declare global {
|
||||
>global : Symbol(global, Decl(b.ts, 0, 26))
|
||||
|
||||
namespace a {
|
||||
>a : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1))
|
||||
|
||||
export const y = 0;
|
||||
>y : Symbol(y, Decl(b.ts, 4, 20))
|
||||
|
||||
export const conflict = 0;
|
||||
>conflict : Symbol(conflict, Decl(b.ts, 5, 20))
|
||||
}
|
||||
}
|
||||
|
||||
declare module "./a" {
|
||||
>"./a" : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1))
|
||||
|
||||
export const z = 0;
|
||||
>z : Symbol(z, Decl(b.ts, 10, 16))
|
||||
|
||||
export const conflict = 0;
|
||||
>conflict : Symbol(conflict, Decl(b.ts, 11, 16))
|
||||
}
|
||||
|
||||
a.x + a.y + a.z + a.conflict;
|
||||
>a.x : Symbol(a2.x, Decl(a.d.ts, 1, 12))
|
||||
>a : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1))
|
||||
>x : Symbol(a2.x, Decl(a.d.ts, 1, 12))
|
||||
>a.y : Symbol(a2.y, Decl(b.ts, 4, 20))
|
||||
>a : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1))
|
||||
>y : Symbol(a2.y, Decl(b.ts, 4, 20))
|
||||
>a.z : Symbol(a2.z, Decl(b.ts, 10, 16))
|
||||
>a : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1))
|
||||
>z : Symbol(a2.z, Decl(b.ts, 10, 16))
|
||||
>a.conflict : Symbol(a2.conflict, Decl(a.d.ts, 2, 12))
|
||||
>a : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1))
|
||||
>conflict : Symbol(a2.conflict, Decl(a.d.ts, 2, 12))
|
||||
|
||||
a2.x + a2.y + a2.z + a2.conflict;
|
||||
>a2.x : Symbol(a2.x, Decl(a.d.ts, 1, 12))
|
||||
>a2 : Symbol(a2, Decl(b.ts, 0, 6))
|
||||
>x : Symbol(a2.x, Decl(a.d.ts, 1, 12))
|
||||
>a2.y : Symbol(a2.y, Decl(b.ts, 4, 20))
|
||||
>a2 : Symbol(a2, Decl(b.ts, 0, 6))
|
||||
>y : Symbol(a2.y, Decl(b.ts, 4, 20))
|
||||
>a2.z : Symbol(a2.z, Decl(b.ts, 10, 16))
|
||||
>a2 : Symbol(a2, Decl(b.ts, 0, 6))
|
||||
>z : Symbol(a2.z, Decl(b.ts, 10, 16))
|
||||
>a2.conflict : Symbol(a2.conflict, Decl(a.d.ts, 2, 12))
|
||||
>a2 : Symbol(a2, Decl(b.ts, 0, 6))
|
||||
>conflict : Symbol(a2.conflict, Decl(a.d.ts, 2, 12))
|
||||
|
||||
78
tests/baselines/reference/exportAsNamespace_augment.types
Normal file
78
tests/baselines/reference/exportAsNamespace_augment.types
Normal file
@@ -0,0 +1,78 @@
|
||||
=== /a.d.ts ===
|
||||
export as namespace a;
|
||||
>a : typeof import("/a")
|
||||
|
||||
export const x = 0;
|
||||
>x : 0
|
||||
>0 : 0
|
||||
|
||||
export const conflict = 0;
|
||||
>conflict : 0
|
||||
>0 : 0
|
||||
|
||||
=== /b.ts ===
|
||||
import * as a2 from "./a";
|
||||
>a2 : typeof a2
|
||||
|
||||
declare global {
|
||||
>global : typeof global
|
||||
|
||||
namespace a {
|
||||
>a : typeof a2
|
||||
|
||||
export const y = 0;
|
||||
>y : 0
|
||||
>0 : 0
|
||||
|
||||
export const conflict = 0;
|
||||
>conflict : 0
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
|
||||
declare module "./a" {
|
||||
>"./a" : typeof a2
|
||||
|
||||
export const z = 0;
|
||||
>z : 0
|
||||
>0 : 0
|
||||
|
||||
export const conflict = 0;
|
||||
>conflict : 0
|
||||
>0 : 0
|
||||
}
|
||||
|
||||
a.x + a.y + a.z + a.conflict;
|
||||
>a.x + a.y + a.z + a.conflict : number
|
||||
>a.x + a.y + a.z : number
|
||||
>a.x + a.y : number
|
||||
>a.x : 0
|
||||
>a : typeof a2
|
||||
>x : 0
|
||||
>a.y : 0
|
||||
>a : typeof a2
|
||||
>y : 0
|
||||
>a.z : 0
|
||||
>a : typeof a2
|
||||
>z : 0
|
||||
>a.conflict : 0
|
||||
>a : typeof a2
|
||||
>conflict : 0
|
||||
|
||||
a2.x + a2.y + a2.z + a2.conflict;
|
||||
>a2.x + a2.y + a2.z + a2.conflict : number
|
||||
>a2.x + a2.y + a2.z : number
|
||||
>a2.x + a2.y : number
|
||||
>a2.x : 0
|
||||
>a2 : typeof a2
|
||||
>x : 0
|
||||
>a2.y : 0
|
||||
>a2 : typeof a2
|
||||
>y : 0
|
||||
>a2.z : 0
|
||||
>a2 : typeof a2
|
||||
>z : 0
|
||||
>a2.conflict : 0
|
||||
>a2 : typeof a2
|
||||
>conflict : 0
|
||||
|
||||
22
tests/cases/compiler/exportAsNamespace_augment.ts
Normal file
22
tests/cases/compiler/exportAsNamespace_augment.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
// @Filename: /a.d.ts
|
||||
export as namespace a;
|
||||
export const x = 0;
|
||||
export const conflict = 0;
|
||||
|
||||
// @Filename: /b.ts
|
||||
import * as a2 from "./a";
|
||||
|
||||
declare global {
|
||||
namespace a {
|
||||
export const y = 0;
|
||||
export const conflict = 0;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "./a" {
|
||||
export const z = 0;
|
||||
export const conflict = 0;
|
||||
}
|
||||
|
||||
a.x + a.y + a.z + a.conflict;
|
||||
a2.x + a2.y + a2.z + a2.conflict;
|
||||
Reference in New Issue
Block a user