Search code examples
propertiestypescriptaccessor

Properties in a module


Is there a way to define a property in a TypeScript module?

None of these compile:

module My {
    // doesnt work
    get Value(): number { return 42; }

    // doesn't work either
    get function Value(): number { return 42; }

    // nope
    function get Value(): number { return 42; }
}

Right now I'm forced to use this:

module My {
    declare var Value: number;
    Object.defineProperty(My, "Value", {
        get: () => 42
    });
}

The second form seems messy to me and the code hinting doesn't really treat it as a read-only property but as a plain variable.

Is there any standard way of defining properties directly inside modules?


Solution

  • No, there's not a way to declare a property on a module in TypeScript using any documented language features.

    You can do it in several slightly round-about techniques.

    A module can extend an existing class or function. So, I've created a class with a static property, and then later created a module that uses the same name as the class.

    class My
    {
        static get Value():Number {
            return 42;
        }
    }
    
    module My {
        var works: boolean = true;
    }
    
    alert(My.Value);
    

    It does generate one oddity in the JavaScript generated code that you wouldn't do manually (and should be removed by most optimizers anyway) ... it will redeclare the variable My when the module is created. This does not cause a run-time issue as the variable was already lifted in JavaScript and will not conflict with the first usage.

    Here's another option:

    module Global {
        class Inner {
            get Value():Number {
                return 42;
            }       
        }   
        export var My;
        My = new Inner();
    }
    
    var My = Global.My;
    alert(My.Value);
    

    While it presents an extra namespace, you can manipulate it however you'd like and use the inner class or change it as needed. This way, the My variable is global, just like it would be as a module.