Properties 模块中的属性

Properties 模块中的属性,properties,typescript,accessor,Properties,Typescript,Accessor,有没有办法在TypeScript模块中定义属性 这些都不能编译: 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; } } 现在我不得不用

有没有办法在TypeScript
模块中定义属性

这些都不能编译:

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; }
}
现在我不得不用这个:

module My {
    declare var Value: number;
    Object.defineProperty(My, "Value", {
        get: () => 42
    });
}
第二种形式在我看来很混乱,代码暗示并没有真正将其视为只读属性,而是将其视为普通变量


是否有任何标准方法可以直接在模块内部定义属性?

不,没有任何方法可以使用任何文档化的语言功能在TypeScript中的
模块上声明属性

你可以用几种稍微绕圈的技巧来做

模块
可以扩展现有的
函数
。因此,我创建了一个带有
静态
属性的类,然后创建了一个
模块
,该模块使用与
相同的名称

class My
{
    static get Value():Number {
        return 42;
    }
}

module My {
    var works: boolean = true;
}

alert(My.Value);
它确实在JavaScript生成的代码中产生了一个您不会手动执行的奇怪之处(并且应该被大多数优化器删除)。。。创建模块时,它将重新声明变量
My
。这不会导致运行时问题,因为该变量已在JavaScript中解除,并且不会与第一次使用冲突

还有一个选择:

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

var My = Global.My;
alert(My.Value);

虽然它提供了一个额外的名称空间,但您可以随意操作它,并使用内部类或根据需要对其进行更改。这样,<代码>我的<代码>变量是全局的,就像是<代码>模块< /> >

,而不是使用<代码>模块<代码>关键字,而是考虑使用<代码>导出< /代码>,它允许你做你想做的事,把文件本身当作一个模块(这是公共的和AMD都是如何工作的)。
//在My.ts中
变量My={
获取值(){
返回42;
}
};
出口=我的;

//在foo.ts中
导入My=require('My');
console.log(My.value);
我在一篇博客文章中更详细地描述了这一点。

我尝试了singleton

let My = {
  get value() {
    return 42;
  }
}

export My
但是遇到了一个问题,即发出的JS仍然说
get value()
,并且在旧版本的节点上不起作用。我尝试了
Object.defineProperty
,但随后失去了TypeScript兼容性。这是我修复这两种情况的桥梁:

interface My {
  value: number
}

// type assertion fixes TypeScript usage
let my = <My>{}
// defineProperty fixes JS usage
Object.defineProperty(my, 'value', {
  get: () => 42
});

export = my;

这似乎比我目前使用的更黑客。此外,类中的属性无法访问模块中的“私有”变量/函数,这有点违背了大多数属性的用途。我不同意这样做更粗糙,因为这只依赖于标准的、受支持的TypeScript。我建议您只导出
My
模块中的一个类,其中包含您想要的功能。TypeScript
模块
不应具有属性(因为该语言不支持它)。编辑的问题包括另一个选项。我实际上使用模块作为模块。。。它们可能有内部类,添加事件监听器和其他类似的东西,所以用它们代替对象要么是不可能的,要么就是非常“不舒服”;TypeScript文件的根成为模块的主体。在模块内部运行的任何过程代码的末尾,都会显式导出值。这是最确定的。请确切告诉我,在运行
tsc-t es5-m amd My.ts
时,生成的输出的哪一部分是无效的EcmaScript 5。此响应来自2014年。3年后(到现在)有变化吗?
import * as my from './my'

my.property // returns 42
// my.property = doesn't work