Search code examples
typescriptsymbolsprivacy

In TypeScript, why are Symbols for Privacy throwing errors for Consumers?


i wish for some privacy for some of my class fields and methods

  • i know symbols aren't really really private, but i just don't want the "private" members just floating around for people to easily use, this is about signalling intent
  • the typescript "private" keyword doesn't do anything to signal intent for privacy, neither by adding an underscore prefix nor by using symbols (not even as an option)
  • i don't want to wait around for typescript to implement the private fields # proposal nor switch to babel now over this

here in my project quizzly i have created some classes which use symbols to access the private members

the pattern is basically:

const _counter = Symbol()

export class CountingThing {
  private [_counter] = 0
}

i thought this is a nice way to implement privacy until typescript finally incorporates the # private field syntax — this works nicely for a javascript-only npm consumers

unfortunately, this pattern doesn't seem to work for typescript consumers of my package

my consumer project gets these errors during typescript compilation:

node_modules/quizzly/dist/components/quizzly-question.d.ts:8:13 - error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.

8     private [_getChoices];
              ~~~~~~~~~~~~~

node_modules/quizzly/dist/components/quizzly-question.d.ts:8:14 - error TS2304: Cannot find name '_getChoices'.

8     private [_getChoices];
              ~~~~~~~~~~~

node_modules/quizzly/dist/components/quizzly-quiz.d.ts:26:13 - error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.

26     private [_getSlottedElements];
              ~~~~~~~~~~~~~~~~~~~~~

node_modules/quizzly/dist/components/quizzly-quiz.d.ts:26:14 - error TS2304: Cannot find name '_getSlottedElements'.

26     private [_getSlottedElements];

but why on earth would the consumer be complaining about private variables, which the consumer shouldn't even have any knowledge about at all?

oddly, the quizzly project itself reports no errors during typescript compilation, this only affects consumers using the .d.ts files

what strategies are available in typescript today, to implement some semblance of privacy?


Solution

  • neither by adding an underscore prefix nor by using symbols (not even as an option)

    I disagree. _foo vs. foo feels very private to me. Its been a pattern in JavaScript for a long long time (2007).

    the typescript "private" keyword doesn't do anything to signal intent for privacy,

    It works for TypeScript consumers just fine. JavaScript consumers know of _, at least if they use any other pure JS projects that compile down to es5 (a vast majority)

    My Suggestion

    private _something 👌🏻