Typescript Equivalent of package scope?
There are no direct ways to enforce this in Typescript. In my experience, the best way to solve this sort of problem is through clear documentation and clear naming patterns.
If there is a unskilled or malicious dev, they will have any number of ways to create havoc and compiler limitations will do little to stop them. However, all reasonably skilled and ethical developers should be able to avoid calling internal, dangerous methods.
My recommendation would be to generate some sort of naming convention. All non-API methods/properties/fields that are public due to language limitations should have the same prefix or suffix.
For example, the way that our team works is the following:
- All non-API public methods/properties/fields are prefixed with
_
. - All non-API public classes are suffixed with
Internal
. - All non-API modules are in an
internal
folder. Eg-src/models
has the models modules that are API.src/models/internal
has the models modules that are not API. - All non-API classes have a comment that documents them as non-API.
Also, we have not done this yet, but are considering creating tslint rules to help enforce these rules. We haven't gone too far down this path yet since we haven't had any devs accidentally using non-API, but this is still a possibility.
In my opinion, proper naming convention, proper document, and proper mentorship is enough to solve this problem, which I agree is a limitation of the Typescript language.
Using a namespace split across files seems like it would accomplish this nicely:
https://www.typescriptlang.org/docs/handbook/namespaces.html#splitting-across-files
As with this in MyNamespace.ts
file:
namespace MyNamespace {
export interface Foo {}
}
And the same namespace plus a reference tag in another file:
/// <reference path="MyNamespace.ts" />
namespace MyNamespace {
export class Bar implements Foo {}
}