Package Seal: magically make an interface sealed when it leaves the package! #21040
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
TypeScript has different type checking within a compilation unit vs when using the d.ts files generated by that compilation. This can be used to modify a type when viewed from outside the package, allowing building the package to type check with one version, but for users to get a different version.
This is probably a bad idea, and very confusing, but it is possible.
It can be used to make a branded version of an interface that is not implementable, but leave it implementable when inside the package to avoid needing to cast to the non-implementable type when outputting instance via the public API.
In this case the branding is done by intersecting with ErasedType which is a non-implementable non constructable token type we already have laying around, but a different approach could be used if desired.
More advanced API transformations could be performed as well, like removing all members ending in "internal" or swapping the interface for some base interface with less members. This could be combined with the branding to make it relatively type safe.
These same approaches can be done across without the in package detection trick, and just for an explicit cast everywhere a value is exposed in the public API: that may be needed for repo instead of package scoped cases.
Reviewer Guidance
The review process is outlined on this wiki page.
If you think this might be useful, let me know.