Open
Description
The internal
Modifier
- We've discussed an
internal
modifier on-and-off since 2015. - High 👍 count, but haven't pursued it.
- Today you can use
/** @internal */
JSDoc comments to mark things as internal, and--stripInternal
. - Previously,
--stripInternal
was not even publicly documented. - Also, have to do hacks to make
.d.ts
bundling work with this. - Would be nice to have something more formal.
- Also,
internal
allows you to know whether something is getting overridden in a subtype.
- Also,
- Idea:
internal
stays in.d.ts
output.- Project package or project boundary.
- Only operates in the same compilation.
- Not allowed to
import
anexport internal
. - At the
tsconfig.json
level, internal access might be granted and asserted in a few ways:-
Maybe an option for specific packages
{ "compilerOptions": { // Grant access to 'consuming-package': "internalsVisibleTo": ["consuming-package"], // Assert access to 'dependency-package': "internalsVisibleFrom": ["dependency-package"], } }
-
Possibly just something on each reference
{ "references": [ { "path": "../package", "allowInternals": true } ] }
-
- What are the rules?
- Can't mix (e.g. no
public
andinternal
in the same declaration).
- Can't mix (e.g. no
- Why not JSDoc?
- Relatively expensive for this.
- What should tools do with
internal
?- Should bundlers limit access to an
internal
member that'sexport *
'd?- We'd sort of hope "no".
- Does the declaration emitter have to worry about this now?
- What happens when you run
keyof
on a type withinternal
?- Probably should do the same thing that
private
does. - But does that mean that
keyof
means something different depending on where it's written.
- Probably should do the same thing that
- How does this work for overload resolution?
- Do overloads get skipped?
- Do they get related appropriately?
- Should bundlers limit access to an
- The "someone subclassed this" issue is not something we've heard a ton of.
- Do most people use
.d.ts
bundlers that can do this post-processing?- No, mostly not.
- Some of our build tooling would be simpler if we had this.
- But doesn't it mean that we're just making other stuff more complex?
- For example,
public
andprivate
overloads can't be mixed today. - Well maybe we do need to explore that restriction.
- For example,
- Also, some of the point of
--stripInternal
is to not make things publicly known and avoid documenting functions to prevent usage. - Back to this question again - what do you do when you have a mapped type?
internal
is inaccessible depending on where it's used.private
andprotected
has this, but it's not witnessable in the majority of code (which is outside of the class).
- Coming back to
keyof
- is this now a location-sensitive operation?- The idea that you will get different types based on instantiation location is not something we've done before.
- Really don't like that.
- The idea that you will get different types based on instantiation location is not something we've done before.
- What do you want?
- Scope visibility to peers.
- Keep existence undocumented.
- Do we really want an ergonomic way for people to import something marked
internal
?- We don't have to do everything listed above.
- Can do this just on the module level.
- Maybe even just that and the property level.
- "Good enough" as
readonly
.
- Cautious but curious around a solution.
- Not convinced that we would have a solution that we'd entirely be happy with.
- Must preserve existing invariants around how type information appears.
- One opinion: sympathetic to a
package
-like modifier, but doesn't entirely solve the problem for our own usage for hiding entities in the resulting declaration file.