Búsqueda de sitios web

En TypeScript, ¿por qué los símbolos para privacidad están causando errores a los consumidores?


Deseo algo de privacidad para algunos de los campos y métodos de mi clase

  • Sé que los símbolos no son realmente realmente privados, pero simplemente no quiero que los miembros "privados" estén flotando por ahí para que la gente los use fácilmente, esto se trata de señalar la intención
  • La palabra clave "private" de TypeScript no hace nada para señalar la intención de privacidad, ni agregando un guion bajo al inicio ni usando símbolos (ni siquiera como opción)
  • No quiero esperar a que TypeScript implemente la propuesta de campos privados # ni cambiar a Babel ahora por esto

aquí en mi proyecto quizzly he creado algunas clases que usan símbolos para acceder a los miembros privados

el patrón es básicamente:

const _counter = Symbol()

export class CountingThing {
  private [_counter] = 0
}

Pensé que esta es una buena manera de implementar la privacidad hasta que TypeScript finalmente incorpore la sintaxis de campo privado # — esto funciona muy bien para consumidores de npm solo de JavaScript

Desafortunadamente, este patrón no parece funcionar para los consumidores de typescript de mi paquete

mi proyecto de consumidor obtiene estos errores durante la compilación de TypeScript:

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];

pero ¿por qué demonios se quejaría el consumidor de las variables privadas, sobre las cuales el consumidor ni siquiera debería tener ningún conocimiento?

Curiosamente, el propio proyecto quizzly no informa errores durante la compilación de TypeScript, esto solo afecta a los consumidores que usan los archivos .d.ts

¿Qué estrategias están disponibles en TypeScript hoy en día para implementar algún tipo de privacidad?

Respuesta #1

ni agregando un guion bajo al principio ni usando símbolos (ni siquiera como opción)

No estoy de acuerdo. _foo frente a foo me parece muy privado. Ha sido un patrón en JavaScript durante mucho, mucho tiempo (2007).

La palabra clave "private" de TypeScript no hace nada para señalar la intención de privacidad,

Funciona perfectamente para los consumidores de TypeScript. Los consumidores de JavaScript conocen _, al menos si usan cualquier otro proyecto puro de JS que se compile a es5 (la gran mayoría)

Mi sugerencia

privado _algo 👌🏻

Respuesta #2

Otra solución es exportar cada símbolo

const _counter = Symbol()

// the export keyword must be added

export const _counter = Symbol()

Esto resuelve los errores de TypeScript para el consumidor

Sin embargo, aumenta la disponibilidad de esos símbolos, lo que facilita a los consumidores usarlos tal como aparecen en la firma pública del módulo