4

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?

2 Answers 2

4
+50

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.

Sign up to request clarification or add additional context in comments.

Comments

4

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

1 Comment

OrigRx.Observable.prototype..., no?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.