TypeScript中是否有一种方法允许一个文件访问另一个文件中的方法,但是不能让它们全局访问?
这个用例就是拥有一个庞大的类,其中包含一些危险的私有方法,不应公开暴露在代码库中的任何地方。我希望能够编写在另一个文件中访问它们的方法,以允许对它们进行逻辑分组,而不必将它们全部放在一个巨大的类中。
理想情况下,像Java的软件包范围之类的内容会让我声明这两个文件可以互相访问#C;危险的方法,但没有其他人。是否有允许这样的TypeScript语言功能?
示例:
A类的方法d1
到d100
都是危险的,不应该是全球可访问的。
B类的方法s1
到s100
可以安全地在项目中公开使用。在进行一些安全检查后,每个s
方法都会调用d
方法。 B类需要能够访问所有d
方法。
C类希望调用任何s
方法,并且应该能够,但不应该能够调用任何d
方法。
但是,正如我理解的Typescript,如果我导出任何d
方法以便B可以调用它们,那么它们也可以被C访问。如果这是Java,我会将A和B放在同一个包中并生成d
方法包范围。
在TypeScript中似乎没有任何与此平行的东西,但有没有任何模拟目标:1)能够破坏单独文件的功能,但2)限制谁可以调用方法?
(是的,我知道一旦它被编译成Javascript,所有的赌注都会关闭。目标是在编译时使用TypeScript作为静态检查器来验证合同。)
答案 0 :(得分:6)
没有直接的方法可以在Typescript中强制执行此操作。根据我的经验,解决此类问题的最佳方法是通过清晰的文档和明确的命名模式。
如果存在不熟练或恶意的开发人员,他们将有多种方法来创建破坏,编译器限制对于阻止它们几乎没有作用。但是,所有合理技能和道德的开发人员都应该能够避免使用内部的,危险的方法。
我的建议是生成某种命名约定。由于语言限制而公开的所有非API方法/属性/字段应具有相同的前缀或后缀。
例如,我们团队的工作方式如下:
_
为前缀。Internal
为后缀。internal
文件夹中。例如,src/models
具有API模型模块。 src/models/internal
的模型模块不是API。此外,我们还没有这样做,但正在考虑创建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模块)。