In my TypeScript project (using only internal modules), I want to include polyfills/extension for an existing library. For this example, I will use the RxJS library but the question/problem is not specific to this library.
The following code is what I came up with:
module MyModule.Rx {
Rx.Observable.prototype.myExtension = function() { /* ... */ };
}
The RxJS definitions (.d.ts files) are used and compiled together with the code. This leads to the following compiler error: 2339 Property 'Observable' does not exist on type 'typeof Rx'
As far as I can tell this happens because I used the same Rx
identifier in MyModule.Rx
. When switching the namespace in the first line to module MyModule.NotRx {
everything works fine - the Observable
type is correctly looked up from the RxJS .d.ts file.
So it seems that the names MyModule.Rx
and the RxJS declared Rx
namespaces are in conflict. I know that I could simply rename my namespace to MyModule.SomethingElse
but that seems somewhat of a hack.
Having all polyfills/extensions for Rx
in the MyModue.Rx
namespace seems a natural choice for me - how can this be done in a clean way?
You can't do that.
Take this code in 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
}
The message displayed in the console is: Object { }
and not test
. Look at the transpiled code:
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 = {}));
The module A.B
is transpiled to two JavaScript variables A
and B
. We can use them in order to access to the exported members of the module: the function fn
is accessible from A.B.fn
, B.fn
and fn
. In the module, the variable B
from the root scope is hidden by the variable B
of the module.
You can't access to a global variable Rx
from a module named Rx
.
As mentioned by Tarh you cannot refer to an outer module if its been shadowed by a local variable. I've +1ed his answer and that should be the accepted answer. I'll just leave a few workarounds:
One workaround which you already know is to rename MyModule.Rx
to something that doesn't have Rx
. An alternative is to capture Rx
with some other name:
import OrigRx = Rx;
module MyModule.Rx {
OrigRx.Observable.prototype.myExtension = function() { /* ... */ };
}
This is very similar to https://stackoverflow.com/a/29021964/390330
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With