TypeScript 中存在名称冲突时如何解决内部模块
How to address internal module when a name conflict exists in TypeScript
在我的 TypeScript 项目(仅使用内部模块)中,我想为现有库包含 polyfills/extension。对于此示例,我将使用 RxJS 库,但 question/problem 并非特定于此库。
下面的代码是我想出来的:
module MyModule.Rx {
Rx.Observable.prototype.myExtension = function() { /* ... */ };
}
RxJS 定义(.d.ts 文件)与代码一起使用和编译。这会导致以下编译器错误:2339 Property 'Observable' does not exist on type 'typeof Rx'
据我所知,这是因为我在 MyModule.Rx
中使用了相同的 Rx
标识符。当将第一行中的名称空间切换为 module MyModule.NotRx {
时,一切正常 - Observable
类型从 RxJS .d.ts 文件中正确查找。
所以看起来名称 MyModule.Rx
和 RxJS 声明的 Rx
命名空间有冲突。我知道我可以简单地将我的命名空间重命名为 MyModule.SomethingElse
但这似乎有些 hack。
在 MyModue.Rx
命名空间中拥有 Rx
的所有 polyfills/extension 对我来说似乎是一个自然的选择 - 如何以干净的方式做到这一点?
你不能那样做。
在 TypeScript 中使用此代码:
var B = 'test';
module A.B {
// Declare a function
export function fn() {
}
// Tests
console.log(B); // Object { }
A.B.fn(); // valid
B.fn(); // valid
fn(); // valid
}
控制台中显示的消息是:Object { }
而不是 test
。查看转译后的代码:
var B = 'test'; // root scope
var A;
(function (A) {
var B; // same name, hide the root scope one
(function (B) {
// Declare a function
function fn() {
}
B.fn = fn;
// Tests
console.log(B); // Object { }
A.B.fn(); // valid
B.fn(); // valid
fn(); // valid
})(B = A.B || (A.B = {}));
})(A || (A = {}));
模块 A.B
被转译为两个 JavaScript 变量 A
和 B
。我们可以使用它们来访问模块的导出成员:函数 fn
可以从 A.B.fn
、B.fn
和 fn
访问。在模块中,根作用域中的变量 B
被模块的变量 B
隐藏。
您无法从名为 Rx
.
的模块访问全局变量 Rx
正如 Tarh 所提到的,如果外部模块被局部变量遮蔽,则不能引用外部模块。我已经 +1 了他的答案,这应该是公认的答案。我将只留下一些解决方法:
您已经知道的一种解决方法是将 MyModule.Rx
重命名为没有 Rx
的名称。另一种方法是使用其他名称捕获 Rx
:
import OrigRx = Rx;
module MyModule.Rx {
OrigRx.Observable.prototype.myExtension = function() { /* ... */ };
}
这与
非常相似
在我的 TypeScript 项目(仅使用内部模块)中,我想为现有库包含 polyfills/extension。对于此示例,我将使用 RxJS 库,但 question/problem 并非特定于此库。
下面的代码是我想出来的:
module MyModule.Rx {
Rx.Observable.prototype.myExtension = function() { /* ... */ };
}
RxJS 定义(.d.ts 文件)与代码一起使用和编译。这会导致以下编译器错误:2339 Property 'Observable' does not exist on type 'typeof Rx'
据我所知,这是因为我在 MyModule.Rx
中使用了相同的 Rx
标识符。当将第一行中的名称空间切换为 module MyModule.NotRx {
时,一切正常 - Observable
类型从 RxJS .d.ts 文件中正确查找。
所以看起来名称 MyModule.Rx
和 RxJS 声明的 Rx
命名空间有冲突。我知道我可以简单地将我的命名空间重命名为 MyModule.SomethingElse
但这似乎有些 hack。
在 MyModue.Rx
命名空间中拥有 Rx
的所有 polyfills/extension 对我来说似乎是一个自然的选择 - 如何以干净的方式做到这一点?
你不能那样做。
在 TypeScript 中使用此代码:
var B = 'test';
module A.B {
// Declare a function
export function fn() {
}
// Tests
console.log(B); // Object { }
A.B.fn(); // valid
B.fn(); // valid
fn(); // valid
}
控制台中显示的消息是:Object { }
而不是 test
。查看转译后的代码:
var B = 'test'; // root scope
var A;
(function (A) {
var B; // same name, hide the root scope one
(function (B) {
// Declare a function
function fn() {
}
B.fn = fn;
// Tests
console.log(B); // Object { }
A.B.fn(); // valid
B.fn(); // valid
fn(); // valid
})(B = A.B || (A.B = {}));
})(A || (A = {}));
模块 A.B
被转译为两个 JavaScript 变量 A
和 B
。我们可以使用它们来访问模块的导出成员:函数 fn
可以从 A.B.fn
、B.fn
和 fn
访问。在模块中,根作用域中的变量 B
被模块的变量 B
隐藏。
您无法从名为 Rx
.
Rx
正如 Tarh 所提到的,如果外部模块被局部变量遮蔽,则不能引用外部模块。我已经 +1 了他的答案,这应该是公认的答案。我将只留下一些解决方法:
您已经知道的一种解决方法是将 MyModule.Rx
重命名为没有 Rx
的名称。另一种方法是使用其他名称捕获 Rx
:
import OrigRx = Rx;
module MyModule.Rx {
OrigRx.Observable.prototype.myExtension = function() { /* ... */ };
}
这与