Typescript等效的包范围?

时间:2017-05-15 05:12:18

标签: typescript typescript2.0

TypeScript中是否有一种方法允许一个文件访问另一个文件中的方法,但是不能让它们全局访问?

这个用例就是拥有一个庞大的类,其中包含一些危险的私有方法,不应公开暴露在代码库中的任何地方。我希望能够编写在另一个文件中访问它们的方法,以允许对它们进行逻辑分组,而不必将它们全部放在一个巨大的类中。

理想情况下,像Java的软件包范围之类的内容会让我声明这两个文件可以互相访问#C;危险的方法,但没有其他人。是否有允许这样的TypeScript语言功能?

示例:

A类的方法d1d100都是危险的,不应该是全球可访问的。

B类的方法s1s100可以安全地在项目中公开使用。在进行一些安全检查后,每个s方法都会调用d方法。 B类需要能够访问所有d方法。

C类希望调用任何s方法,并且应该能够,但不应该能够调用任何d方法。

但是,正如我理解的Typescript,如果我导出任何d方法以便B可以调用它们,那么它们也可以被C访问。如果这是Java,我会将A和B放在同一个包中并生成d方法包范围。

在TypeScript中似乎没有任何与此平行的东西,但有没有任何模拟目标:1)能够破坏单独文件的功能,但2)限制谁可以调用方法?

(是的,我知道一旦它被编译成Javascript,所有的赌注都会关闭。目标是在编译时使用TypeScript作为静态检查器来验证合同。)

4 个答案:

答案 0 :(得分:6)

没有直接的方法可以在Typescript中强制执行此操作。根据我的经验,解决此类问题的最佳方法是通过清晰的文档和明确的命名模式。

如果存在不熟练或恶意的开发人员,他们将有多种方法来创建破坏,编译器限制对于阻止它们几乎没有作用。但是,所有合理技能和道德的开发人员都应该能够避免使用内部的,危险的方法。

我的建议是生成某种命名约定。由于语言限制而公开的所有非API方法/属性/字段应具有相同的前缀或后缀。

例如,我们团队的工作方式如下:

  1. 所有非API公共方法/属性/字段都以_为前缀。
  2. 所有非API公共类都以Internal为后缀。
  3. 所有非API模块都位于internal文件夹中。例如,src/models具有API模型模块。 src/models/internal的模型模块不是API。
  4. 所有非API类都有一条注释,将其记录为非API。
  5. 此外,我们还没有这样做,但正在考虑创建tslint规则以帮助实施这些规则。我们没有走太远这条道路,因为我们没有任何开发人员意外地使用非API,但这仍然是一种可能性。

    在我看来,正确的命名约定,适当的文档和适当的指导足以解决这个问题,我同意这是对Typescript语言的限制。

答案 1 :(得分:1)

使用在文件之间拆分的名称空间似乎可以很好地完成此任务:
https://www.typescriptlang.org/docs/handbook/namespaces.html#splitting-across-files

与此类似,在typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); 文件中:

2.2.7

相同的名称空间以及另一个文件中的参考标记:

factory.setRecordInterceptor(new RecordInterceptor);

答案 2 :(得分:0)

我会使用Rob提出的方法隐藏危险方法:将A类放在与B类相同的文件中。导出B类,但不要导出A类。这样,A类只能用于B级。当然,作为替代方案,你可以创建一个巨大的课程,但你对这条道路犹豫不决......

你应该注意:TypeScript编译为JavaScript,因此从JavaScript的角度来看,每一个不安全的代码都可用于不需要的用法。

答案 3 :(得分:0)

TypeScript中没有等效的Java包范围,但有时确实需要。这是我的解决方案:

export class Foo {

    private doSomething(): void {
    //do something
    }
}

interface FooUnlocker {

   doSomething(): void;
}

const foo: Foo = new Foo();
(<FooUnlocker><any>foo).doSomething();

优点-需要额外的约定,例如_doSomething()等,代码干净,我们有编译检查。

缺点-我们需要同步Foo和FooUnlocker。

节点,该FooUnlocker不会导出,因此仅在模块内可见(如果使用ES6模块)。