I was reading the release notes for the TypeScript 3.8 beta the other day and there’s a particular feature in there that caught my eye, Private Fields. This is support for the stage 3 proposal which means it’s a candidate for inclusion in a future language version (more info on the stages can be found here).
What I found interesting is that although TypeScript has supported a
You’ll see the new syntax in the
#name field that indicates it’s a private field. If we pass this through the compiler we’ll get this:
We’ll come back to the generated functions
__classPrivateFieldGet shortly, let’s first look at the class:
Notice there’s a variable generated called
_name that is an instance of a
constructor it calls
_name.set(this, void 0);, so it’s initialising the value in the store to
void 0 (which is a fancy way to write
undefined). Now, if we were to give the field an initial value like this:
It’s change the generated code to use
_name.set(this, "");. Next it uses one of the generated functions,
__classPrivateFieldSet, which does what you’d guess from the name, sets the value in the
WeakMap for the current instance of the class to the value provided (it does some error checking too). Then when we want to access the value the
__classPrivateFieldGet function is used to get the value back out of the
WeakMap that contains it.
Something I also noticed when playing around is that if you were to add another private field:
The generated code now looks like this:
We’ve got two
WeakMap’s, one for each of the fields.
TypeScripts use of the
WeakMap and the instance of the class as the key is quite an ingenious one when it comes to doing private fields for a class, but I do wonder what the trade off would be in memory consumption, since every class will name n number of
WeakMap instances, and do they take up much memory to the point it could be impactful?
None the less it does give me ideas for when I’m building applications and I want to have restricted access to parts of a type, using a
WeakMap as a store might just do the trick.