Typescript: Implementar propuesta de campos privados

Creado en 26 jul. 2016  ·  134Comentarios  ·  Fuente: microsoft/TypeScript

Creo que sería bueno tener la propuesta de campos privados de la

Actualmente, la propuesta solo incluye _propiedades_ privadas, pero es probable que se sigan los métodos. Además, la parte más importante de la propuesta es que las propiedades privadas solo están disponibles dentro de la propia clase.

Committed Fixed Suggestion

Comentario más útil

No creo que la gente esté contenta con una solución no "privada" basada en palabras clave.

Todos 134 comentarios

¿Qué piensa el equipo de TypeScript sobre la sintaxis y el uso de un prefijo de símbolo / carácter?

Personalmente, creo que se ve horrible , pero aparentemente hay limitaciones técnicas (los usos deben identificar la visibilidad, por razones que no comprendo completamente).

Sería triste ver que TypeScript pierde la sintaxis privada / protegida actual, que es mucho más limpia y coherente con otros lenguajes. ¿Es probable que esto suceda? ¿Existen alternativas?

Para agregar a esto, se habla sobre la posibilidad de cambiar los símbolos # y @ (es decir, usar # para decoradores), lo que obviamente también tendría un efecto en TypeScript .

Creo que también es "horrible". Creo que, al igual que el operador de enlace :: , que en realidad no llegó muy lejos, vale la pena esperar incluso intentar implementarlo hasta que avance un poco más en el camino con T39. Sospecho que será un viaje un poco difícil. Además, sospecho que la emisión descendente para admitirlo será bastante difícil, debido a la necesidad de reescribir cada sitio de acceso.

los usos necesitan identificar la visibilidad, por razones que no comprendo completamente

Principalmente porque necesita identificar en el sitio de uso cómo buscar la propiedad, ya que necesita un algoritmo de búsqueda diferente para que las clases descendientes puedan reutilizar los mismos nombres privados sin necesidad de "conocer" las propiedades privadas del ancestro.

Una ventaja de la sintaxis propuesta es que puede omitir this y simplemente usar #field directamente. Además, el sigilo se puede intercambiar con decoradores (https://github.com/tc39/proposal-private-fields/issues/32) y en su lugar se usaría @ , por lo que usaría @field , como Ruby. ¿Todavía te parece fea esta sintaxis?

No creo que la gente esté contenta con una solución no "privada" basada en palabras clave.

No veo una buena manera de hacerlo mientras se admite eval como lo hace JavaScript: un token concreto permite cierta diferenciación y hace posible admitir un estado privado que no se basa en un sistema de tipos estáticos como en TypeScript . Hemos discutido una serie de alternativas de sintaxis en https://github.com/tc39/proposal-private-fields/issues/14 , y no veo la sintaxis actual de TypeScript como algo que pueda funcionar correctamente todo el tiempo en un entorno JS totalmente general.

Principalmente porque necesita identificar en el sitio de uso cómo buscar la propiedad, ya que necesita un algoritmo de búsqueda diferente para que las clases descendientes puedan reutilizar los mismos nombres privados sin necesidad de "conocer" las propiedades privadas del ancestro.

Ojalá supiera más sobre cómo funciona JavaScript internamente. Pensé que funcionaría de la forma en que se describe aquí y aquí , pero aparentemente no. Todavía me resulta difícil creer que eso tenga un impacto significativo en el rendimiento, pero no hay cifras para comparar.

¿Todavía te parece fea esta sintaxis?

Básicamente, sí. Más aún, lo encuentro inconsistente con el resto de la sintaxis de JavaScript, así como inconsistente con muchos otros lenguajes:

| Idioma | Sintaxis | Notas |
| --- | --- | --- |
| C # | privado int x; | |
| C ++ | privado:
int x; | |
| Java | privado int x; | |
| PHP | privado $ x; | |
| Python | __x | "sin comentarios" |
| Ruby | privado
método def
# ...
fin | Es un método, pero los campos son privados.
por defecto, creo. |
| TypeScript | privado x; | |
| Visual Basic | Privado x como entero | |

Todos menos _uno_ de los lenguajes anteriores usan la palabra clave private , y parece que Python realmente no tiene un estado privado "adecuado" de todos modos.

Con la excepción de Python (nuevamente), ninguno de los lenguajes formatea declaraciones de campo o accesos de campo de manera diferente dependiendo de la visibilidad, y todos permiten nuevos modificadores de visibilidad si alguna vez es necesario.

También siento que tanto # como @ funcionan mejor para cosas como decoradores, que están ( en palabras de Kevin ) "sintácticamente 'fuera' del flujo imperativo".

No veo una buena manera de hacerlo mientras se admite la evaluación general como lo hace JavaScript

¿Sería posible explicar este problema en términos sencillos? (tal vez en https://github.com/tc39/proposal-private-fields/issues/14)

Sería bueno tener una lista de estos problemas con ejemplos en un solo lugar, para que haya algo a lo que referirse.

Todavía me resulta difícil creer que eso tenga un impacto significativo en el rendimiento, pero no hay cifras para comparar.

Lo haría, si desea que sea realmente privado en lugar de solo una convención como lo es en TypeScript. Siempre que busca una propiedad en JavaScript, el proceso es esencialmente así:

  1. Mire el ejemplo de propiedad propia.
  2. Si no tiene propiedad propia, busque el prototipo de propiedad propia.
  3. Asciende la cadena de prototipos hasta que no se encuentre ninguna propiedad.
  4. Si se encuentra, trate con el descriptor de propiedad (se puede escribir, obtener, establecer, configurable)
  5. Si no se encuentra y lee, devuelva undefined o escriba, establezca el valor como propiedad propia si no está sellado o congelado.

Ahora, con privados sin patrón en su nombre, no tendrías propiedades propias, tendrías algo así como propiedades privadas propias que no ascenderían a una cadena de prototipos. Entonces tendría que buscarlos allí también para cada operación que pueda acceder a las propiedades privadas, porque no puede estar seguro de a cuál se hace referencia. Buscarlo de la manera normal y luego solo si no se encuentra buscando en privado podría ser muy peligroso, porque ¿qué pasa si encuentra algo en la cadena de prototipos, pero también hay una versión privada?

El mayor desafío es que las clases de JavaScript siguen siendo un nombre poco apropiado. Son esencialmente azúcar sintáctico para funciones de constructor de herencia prototípicas. Se me ocurrió un pensamiento que intentaré agregar a tc39 / proposition-private-fields # 14.

¿Sería posible explicar este problema en términos sencillos?

Si requiere volver a escribir el sitio de la llamada, nunca podrá admitir cosas como:

class Foo {
    private foobar: string;
    baz() {
        const p = 'foo' + 'bar';
        console.log(this[p]);
    }
}

O cualquier uso de estructuras similares a eval . Puede optar por no admitir cosas como el acceso al índice para usuarios privados o no admitir evaluaciones, pero luego "¿por qué molestarse?". Casi todo esto se ha señalado de una forma u otra en la propuesta, pero la gente sigue siendo "pero a mí me gusta lo privado" 😁.

no tendrías propiedades propias, tendrías algo así como propiedades privadas propias

Si tuviera un solo conjunto de propiedades con un elemento visibility en el descriptor, supongo que el problema es que, si la propiedad no existiera en el objeto actual, no sabría si ascender o no cadena prototipo.

Si requiere volver a escribir el sitio de la llamada, nunca podrá admitir cosas como ...

AFAIK, eso no será compatible de todos modos ( ref ).

Todavía no sigo realmente el caso eval. Pensé que las verificaciones de propiedad se realizarían en tiempo de ejecución, después de que se hubieran calculado los nombres de las propiedades.

pero la gente sigue siendo "pero me gusta lo privado"

Intento no ser una de esas personas y comprender los problemas, pero la sintaxis propuesta simplemente me incomoda. =)

Bien, creo que ahora entiendo el caso eval / rewrite. Los sitios de uso dentro de la clase se reescribirán para indicar la visibilidad en función de las propiedades declaradas, y eso no sería posible a menos que sean búsquedas simples.

Si tuviera un solo conjunto de propiedades con un elemento de visibilidad en el descriptor, supongo que el problema es que, si la propiedad no existiera en el objeto actual, no sabría si ascender o no en la cadena de prototipos.

Mmm. Pero si no existe en la clase actual, ¿no es por definición no privado? Si es así, tendría que ascender en la cadena de prototipos de todos modos (como con las búsquedas regulares de propiedad pública). No habría trabajo adicional para el acceso private .

(Posiblemente me esté perdiendo algo obvio)

Pero si no existe en la clase actual, ¿no es por definición no privado? Si es así, tendría que ascender en la cadena de prototipos de todos modos (como con las búsquedas regulares de propiedad pública).

No, no quieres ascender. Las etiquetas privadas no se heredan y las subclases pueden reutilizar las privadas sin preocuparse por las colisiones de enmascaramiento / nombre.

@ glen-84 Ambas publicaciones que mencionaste indican problemas con el estado privado sin sigilo. ¿Tiene ideas para soluciones a esos problemas? Creo que complicar la cadena de búsqueda sería riesgoso en cuanto a compatibilidad, haría que JavaScript sea más difícil de implementar con un buen rendimiento (posiblemente haciendo que los programas existentes sean más lentos), sería básicamente imposible de cuadrar con los Proxies y, en general, complicaría significativamente el modelo mental del lenguaje (que ya tiene un sistema de objetos relativamente complejo).

En la comparación entre idiomas, menciona Ruby. Creo que Ruby es un buen ejemplo de estado privado _con_ un sigilo-- @ . Puede llamar a los métodos getter y setter sin un sigilo.

No, no quieres ascender. Las etiquetas privadas no se heredan y las subclases pueden reutilizar las privadas sin preocuparse por las colisiones de enmascaramiento / nombre.

Me refería a subir si la propiedad no estaba en la clase actual, para buscar una propiedad pública o protegida.

Ambas publicaciones que mencionaste indican problemas con el estado privado sin sigilo. ¿Tiene ideas para soluciones a esos problemas?

Es muy difícil para mí hacer eso, como alguien que no comprende el funcionamiento interno de JavaScript.

You'd have to somehow encode a "private key" into each lexical environment.

No tengo idea de lo que esto significa. ¿Para qué sirve? ¿Es imposible de hacer?

You'd have to change the semantics of each and every property access (because any property access might result in a private field). Engines are highly optimized around the current property lookup semantics.

¿Tan altamente optimizado que un solo interruptor en la visibilidad afectaría significativamente el rendimiento?

Would for-in enumerate over these properties?

Supongo que dependería del contexto. Dentro de la misma clase, sí. Sin embargo, esta no es una razón para no usar private , es un detalle de implementación y es probable que otros lenguajes ya hayan respondido a estas preguntas.

Can someone shadow a private property with a normal property lower on the prototype chain? What about the reverse?

Probablemente sí (aumenta la visibilidad) a la primera pregunta y no a la segunda. Nuevamente, todo esto se ha hecho antes, ¿no es así?

How do you prevent leaking the names of private fields to clients that shouldn't know that information? This is probably a fatal information leak.

La visibilidad es solo una herramienta para encapsular y definir una interfaz pública. El 99% de los desarrolladores probablemente no se preocupan por las "fugas de información". Dicho esto, sugerí dos características separadas aquí . Quizás esta propuesta podría llamarse de otra manera, como "estado oculto" o "estado seguro", y permitir que algo como estado privado / protegido se implemente de manera diferente.

All of this runtime stuff is going to be terrible for performance

Utilice "estado oculto / seguro" si desea perf. : D Con toda seriedad, ¿de qué tipo de pérdida de rendimiento estamos hablando? Quizás alguien pueda crear un prototipo. =)

Also, we couldn't use such a solution to self-host the built-ins

¿No serían realmente malos para el rendimiento los elementos integrados de autohospedaje (si siquiera entiendo lo que eso significa)? Si no ... use "estado oculto / seguro" y no visibilidad privada / protegida de nivel superior.

Creo que complicar la cadena de búsqueda sería arriesgado en cuanto a compatibilidad

No soy la primera / única persona en pensar que así es como podría / podría funcionar. Usted accede a una propiedad, busca un descriptor para ver la visibilidad y responde en consecuencia. No parece complicado si no tienes idea de cómo funcionan realmente las cosas en JS. Realmente necesito leer un curso intensivo sobre algoritmos de búsqueda interna / de propiedad de JS. = P

Creo que Ruby es un buen ejemplo de estado privado con un sigilo - @

Ruby ni siquiera es un lenguaje de la familia C, y parece que no hay campos públicos, sino solo getters y setters (accesores). La propuesta actual del estado privado tiene múltiples declaraciones una al lado de la otra, con el mismo propósito general (declarar propiedades), pero sintaxis visiblemente diferentes e inconsistentes.

Con todo lo dicho, estoy fuera de mi alcance aquí, y lo más probable es que esté agregando más ruido que valor, así que trataré de guardar silencio y dejar que los expertos lleguen a un consenso.

Discutiré este deseo con TC39 y veremos si podemos encontrar otras ideas sobre cómo evitar un prefijo. No tengo ninguno, personalmente. Tenga en cuenta que, si TypeScript decide implementar campos privados, todavía se encuentran en la Etapa 1 en TC39 y, por lo tanto, están sujetos a cambios.

¿Qué piensa el equipo de TypeScript sobre la sintaxis y el uso de un prefijo de símbolo / carácter?

Personalmente creo que se ve horrible ...

Tenga en cuenta que he hecho una sugerencia para deshacerme de la horrible sintaxis # .

@ shelby3 Desafortunadamente, no veo eso como una opción realista. tl; dr, tenemos que preocuparnos de cómo interactuará todo con eval ; no incluir un sigilo hace que todo sea "demasiado dinámico" para funcionar correctamente.

@littledan He seguido ahí ahora y he presentado maximizar la compatibilidad con TypeScript . Sin embargo, ahora entiendo por qué debemos declarar la privacidad de los argumentos de métodos sin tipo.

@isiahmeadows

En su mayoría sustituirá a la implementación pseudo-privada actual [...] Además, la parte más importante de la propuesta es que las propiedades privadas solo están disponibles dentro de la propia clase.

Espero que no sustituya a la implementación pseudo-privada. Creo que la disponibilidad solo dentro de una clase en realidad no es algo tan bueno (dado que por disponibilidad te refieres a accesibilidad ). Admito que puede haber situaciones especiales en las que tenga sentido tener propiedades estrictamente privadas e inaccesibles, por ejemplo, por motivos de seguridad. También admito que, obviamente, es confuso para las personas familiarizadas con otros lenguajes, que private realidad no sea tan privado en JavaScript. Pero aparte de las razones de seguridad, en mi opinión, la mayoría de los desarrolladores deberían usar private mayor parte del tiempo solo para definir un contrato, pero no para controlar la accesibilidad.

Por ejemplo, desde la perspectiva de los arquitectos, creo que algo muy bueno acerca de la palabra clave TS private y su naturaleza pseudoprivada es

  • que permite expresar el contrato de la interfaz de un tipo y cómo debe ser utilizada por los clientes
  • que el compilador de TS compruebe el contrato en el momento de la compilación
  • que todavía puedo "violar" conscientemente el contrato en tiempo de ejecución, especialmente para las pruebas unitarias de caja blanca.

Accesibilidad de las propiedades privadas en tiempo de ejecución muy mucho contribuye a la capacidad de prueba porque soy capaz de inyectar estado privada en una clase bajo prueba por sólo la creación de sus campos privados (a máquina de escribir recomiendo el uso de notación de corchetes en lugar de any moldes debido a una mejor soporte de refactorización), por ejemplo:

let instance: ClassUnderTest = new ClassUnderTest();
instance["_privateField"] = "My injected state";

No es necesario un código de prueba complicado solo para configurar una clase con un estado particular (privado).
Otra ventaja de las propiedades pseudo-privadas es que son esenciales para el parcheo de monos .

No creo que la comunidad de TypeScript cambie felizmente todas sus líneas private variable a private #variable .

Desde la perspectiva de TypeScript, la mayoría de nosotros estamos contentos con nuestras encantadoras y dulces ilusiones de un buen lenguaje (intellisense, errores de tiempo de compilación, tipos, varios azúcares). Estas ilusiones nos brindan una mejor experiencia de desarrollo, escribimos mejor código más rápido. Esta es la razón principal por la que usamos TS además de la transpilación ESNext, pero para esta última está Babel y eso es mejor (o al menos era mejor cuando lo verifiqué por última vez).

No estoy hablando de esos pocos que realmente quieren algo más de las variables privadas que un azúcar sintáctico en sus archivos fuente. Creo que esos tipos necesitan algo más fuerte, quizás más cercano al código nativo.

Pero para el resto de nosotros: realmente no necesitamos JS privado. Necesitamos las variables simples y fáciles private convenient tal como las usamos en C ++, Java, C #, etc.

Vote por una solución que no sea una molestia para nosotros. ¿Quizás privado suave? Porque dudo que queramos el sigilo privado #variable . ¿O quizás TS private y ES private serían conceptos diferentes? Feo.

@igabesz

No creo que la comunidad de TypeScript cambie felizmente todas sus líneas private variable a private #variable

En realidad, con esa propuesta, private sería innecesario. En cambio, el sigilo # reemplaza por completo sin conflicto.

Pero para el resto de nosotros: realmente no necesitamos JS privado. Necesitamos las variables privadas convenientes, simples, fáciles, tal como las usamos en C ++, Java, C #, etc.

El privado de TypeScript es privado suave, como el de la mayoría de los lenguajes OO. Incluso las variables privadas de Java siguen siendo técnicamente privadas suaves, porque todavía son accesibles con una trampilla de escape. JS private es equivalente a usar un cierre, excepto que aún puede acceder al estado privado de instancias que no sean this .

Vote por una solución que no sea una molestia para nosotros. ¿Quizás privado suave? Porque dudo que queramos el sigilo privado #variable. ¿O tal vez TS privado y ES privado serían conceptos diferentes? Feo.

Serían conceptos diferentes, pero en general, las trampillas de escape rara vez son útiles en la práctica. La excepción principal es la inspección de objetos (por ejemplo, herramientas de desarrollador, Node.js util.inspect ), pero la mayoría están definidas por el host y ya usan API nativas privilegiadas ahora, por lo que no hay una necesidad urgente de agregarlas a la especificación.

Además, una vez que ES haya estandarizado el estado privado, TS lo adoptará y probablemente desaprobará su propio mecanismo soft-private, que se eliminará en la próxima versión principal. Siempre ha sido un superconjunto estricto de ES, y ha agregado (funciones asíncronas), cambiado (clases) y / o desaprobado ( /// <amd-dependency /> ) características según sea necesario a medida que ES evoluciona, para mantenerse como un estricto superconjunto y no duplicar la especificación actual.

Además, una vez que ES haya estandarizado el estado privado, TS lo adoptará y probablemente desaprobará su propio mecanismo soft-private, que se eliminará en la próxima versión principal.

😭

Además, una vez que ES haya estandarizado el estado privado, TS lo adoptará y probablemente desaprobará su propio mecanismo soft-private, que se eliminará en la próxima versión principal.

Esta no es la posición del equipo TS. no tenemos planes de desaprobar nada en el corto plazo.
Si la propuesta estatal privada alcanza el estado correcto, TS la implementará. No creo que esto tenga ninguna implicación en los privados, ya que TS los implementa hoy.

@mhegazy Está bien. Me quedo corregido. (Fue una suposición bien fundamentada, por cierto).

La propuesta de campos de clase se encuentra ahora en la etapa 2, así que me alegro de que el equipo de TypeScript esté pensando en esto y esté listo para seguir los estándares de EcmaScript 💯

Si la propuesta estatal privada alcanza el estado correcto, TS la implementará.

@mhegazy ¿Es la etapa 3 el momento correcto para implementar?

EDITAR: Es posible que haya encontrado mi respuesta 😄

@styfle vea la discusión de las notas de la reunión de diseño (# 16415) que discute las consideraciones actuales sobre la implementación.

¿Es la Etapa 3 el momento correcto para implementar?

si. Estamos empezando a investigar los diferentes diseños posibles para esta función.

La propuesta de Campos de la clase se encuentra ahora en la Etapa 3. (A partir de hace un mes)

Mientras que los campos de la clase alcanzaron la Etapa 3, los Métodos privados y los Accesores siguieron a eso, y estuvieron en la Etapa 2 hasta ayer cuando se trasladó a la Etapa 3. Ahora todo lo necesario para dirigirse a los miembros privados de las clases está en la Etapa 3.

¿Alguna actualización sobre la posición / progreso del equipo de TS en la adopción de la sintaxis #[field] ahora que ha estado en la etapa 3 por un tiempo? Personalmente, realmente no me gusta y prefiero la palabra clave existente private TS, pero al mismo tiempo quiero estar lo más cerca posible de los estándares.

Personalmente, realmente no me gusta, y prefiero la palabra clave privada existente de TS

yo tambien, es tan feo

pero @mhegazy me gustaría (intentar) hacer esto, ¿podría?

El análisis no debería ser malo (casi un nuevo modificador que es solo un token, casi), pero la verificación de tipo será una molestia (ya que tendremos dos tipos diferentes de privados que deberán compararse de alguna manera), y el La emisión de nivel inferior es atroz (porque bajar el nivel de la privacidad real en tiempo de ejecución es una gran transformación: @rbuckton tiene ideas al respecto, y tal vez una implementación (no lo sé con certeza; tiene muchas de esas en su bifurcación)). Técnicamente, no podemos evitar que lo intentes, pero no lo recomendaría, si puedes encontrar algo más que prefieras probar, y no puedo garantizar que estemos listos para aceptarlo una vez que hayas terminado. Además, aunque los campos y métodos privados han avanzado, todavía está un poco incompleto hasta que las estadísticas privadas (y posiblemente los decoradores ) también avancen (dada la forma en que interactúan todos, puede ser mejor agregarlos todos a la vez).

Basta decir que hay mucho aquí.

@weswigham Ok, me rindo 😂

Aquí hay un aviso que yo (con

Actualización: Nuestro trabajo en progreso está aquí .

si. Estamos empezando a investigar los diferentes diseños posibles para esta función.

Tampoco me gusta la sintaxis # , pero entiendo las razones técnicas detrás de esta sintaxis. @mhegazy Lo que realmente me gustaría que hiciera un equipo de TypeScript después de implementar una nueva propuesta para pensar qué va a hacer TypeScript con implementaciones obsoletas como namespace , private que se pueden usar pero generalmente deberían no, ya que existe una mejor forma estándar de hacer lo mismo o casi lo mismo.

También quiero agregar mis pocos centavos sobre protected . Si (ahora con suerte) vamos a eliminar / desaprobar la palabra clave private algún día, creo que está bien hacer lo mismo con la palabra clave protected . Sé que la mayoría de la gente puede estar en desacuerdo, pero sí, los visores de visibilidad adicionales a veces pueden ser útiles, pero el valor general no es alto en mi humilde opinión.

@pleerock ,

Esto es lo que esperaría ver de TypeScript:

class Example {
    private a = 1;
    #b = 2;
}

Emit (apuntando a ESNext):

class Example {
    a = 1;
    #b = 2;
}

Emit (apuntando a ESNext, con una nueva opción de compilador para emitir campos marcados como privados como campos privados de ES):

class Example {
    #a = 1;
    #b = 2;
}

Eso debería ser compatible con versiones anteriores, al mismo tiempo que le permite usar campos privados de ES con una sintaxis limpia.

@ glen-84, por supuesto que lo sería, estaba hablando de un plan a largo plazo sobre palabras clave y sintaxis obsoletas

No tenemos planes de desaprobar ninguna sintaxis o palabras clave.

Tampoco creo que tengamos una opción de ningún tipo para transpilar private en # - tienen un comportamiento esperado diferente; # es privacidad estricta en tiempo de ejecución, mientras que private es solo privacidad en tiempo de diseño.

@weswigham Yo @RyanCavanaugh sí, esa era la respuesta esperada. Pero aún así, aplicaría al menos alguna estrategia para que los nuevos usuarios eviten el uso de espacios de nombres / palabras clave privadas porque, en mi humilde opinión, se volvieron obsoletos con las últimas propuestas de ecmascript.

La gente generalmente lo resuelve basándose en la lectura de documentación, que, por supuesto, actualizamos. module foo { todavía está en el idioma, pero básicamente ya no se ve en la naturaleza, excepto en bases de código muy antiguas que son anteriores a namespace foo { .

@RyanCavanaugh es bueno escuchar eso. Pero aún creo que las nuevas personas que vienen de c #, digamos, definitivamente intentarán usar espacios de nombres (no todos, pero algunos de ellos). Supongo que lo mismo podría suceder con los usuarios que provienen de otros idiomas: comenzarán a usar privado en lugar de # y esto tiende a ser más masivo que el ejemplo con espacios de nombres

Tampoco creo que tengamos una opción de ningún tipo para transpilar lo privado en # - tienen un comportamiento esperado diferente; # es privacidad estricta en tiempo de ejecución, mientras que privado es solo privacidad en tiempo de diseño.

D'oh. Tenía la esperanza de que también pudiéramos usar opcionalmente private para privacidad estricta, para evitar la ... sintaxis desafortunada.

De todos modos, soft-private es probablemente suficiente para mis casos de uso (actuales).

Creo que sería genial incluir este soporte de sintaxis en la próxima versión 3 de TypeScript, ya que esta característica es enorme y la versión 3 parece una buena ocasión para que la gente comience a usar la nueva sintaxis # .

EDITAR: maldita sea, olvidé que la versión 3 ya está lanzada.

Solo para su información, hay algunos cambios recientes sobre campos privados / ranuras / lo que sea en el repositorio de la propuesta TC39, por lo que ni siquiera es seguro que la propuesta en su forma actual lo haga. Aquí hay un par de cuestiones relevantes:

No soy TC39, pero mi sugerencia personal para todos es primero esperar a que la sintaxis se solidifique nuevamente (posiblemente esperar a la etapa 4) y luego implementarla.

FWIW: No interpretaría la discusión en tc39 / proposition-class-fields # 100 como indicativa de algo en particular. # no es bonito a primera vista, pero no se ha sugerido una forma sintáctica preferible y la única sintaxis que la gente parece querer es manifiestamente no viable. Es necesario que haya un sigilo de prefijo de algún tipo y todos los intentos de permitir que this.someProp sea ​​privado están condenados al fracaso.

Me doy cuenta de que suena bastante despectivo, pero, francamente, esa es mi intención: ninguno de los quejosos en esos hilos se ha involucrado de manera significativa con los problemas técnicos centrales que se abordan en los hilos existentes o en las Preguntas frecuentes. Es deprimente como diablos leer los hilos en ese repositorio y ver explicaciones largas y correctas de por qué se necesita un sigilo.

Si el final del juego es que nadie usa campos privados a menos que realmente necesiten

Estoy de acuerdo en que probablemente no sea un tema ideal para mencionar, pero el otro,
tc39 / proposition-class-fields # 106, es probablemente mucho más indicativo: hay
discusión seria sobre el uso de mapas débiles en su lugar, entre otras cosas, porque
la interoperabilidad de proxy simplemente apesta.


Isiah Meadows
[email protected]
www.isiahmeadows.com

El lunes 30 de julio de 2018 a las 3:38 p.m., Ryan Cavanaugh [email protected]
escribió:

FWIW No interpretaría la discusión en
tc39 / campo-clase-propuesta # 100
https://github.com/tc39/proposal-class-fields/issues/100 para ser
indicativo de algo en particular. # no es bonito a primera vista, pero
no se ha sugerido una forma sintáctica preferible y la única sintaxis que
la gente parece querer es manifiestamente no viable. Tiene que haber un prefijo
sigilo de algún tipo y todos los intentos de permitir que this.someProp sea privado
están condenados al fracaso.

Me doy cuenta de que suena bastante despectivo, pero, francamente, esa es mi intención:
Ninguno de los quejosos en esos hilos se ha comprometido significativamente con el
problemas técnicos centrales abordados en los hilos existentes o en las preguntas frecuentes. Es
deprimente como diablos para leer los hilos en ese repositorio y ver mucho
Las explicaciones
suelo.

Si el final del juego es que nadie usa campos privados a menos que realmente
necesitan una gran privacidad en el tiempo de ejecución, probablemente sea un buen resultado para la web en
términos de rendimiento y depuración.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/Microsoft/TypeScript/issues/9950#issuecomment-408984395 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AERrBGCphyQUu5lJQW7lgsqALLL3e0_Wks5uL2DLgaJpZM4JVDwV
.

Existe cierta discusión sobre el uso de WeakMaps, pero no veo cómo eso mejoraría la interacción con Proxy. Invitaría a cualquier miembro de TC39 que tenga otra idea sobre cómo deberían funcionar las funciones de clase privada a presentarla al comité para recibir comentarios; Actualmente, esta propuesta se encuentra en la Etapa 3 y, teóricamente, representa la posición de consenso del comité. Muchas personas se comprometieron a alcanzar un objetivo compartido de habilitar esta función, incluso cuando son posibles otros diseños.

Estoy trabajando para organizar una discusión entre marcos sobre cómo usar Proxy para observar mutaciones de objetos y cómo debería interactuar con los campos privados. Avísame si te gustaría unirte a la conversación.

@RyanCavanaugh

FWIW: No interpretaría la discusión en tc39 / proposition-class-fields # 100 como indicativa de algo en particular. # no es bonito a primera vista, pero no se ha sugerido una forma sintáctica preferible y la única sintaxis que la gente parece querer es manifiestamente no viable. Es necesario que haya un sigilo de prefijo de algún tipo y todos los intentos de permitir que this.someProp sea ​​privado están condenados al fracaso.

Más tarde en esto, pero en realidad hay una propuesta que sugiere la sintaxis this->var .

Por supuesto, esta propuesta probablemente esté muerta ("el comité no estaba entusiasmado" es la única razón que he podido encontrar). Pero sí se ha propuesto una sintaxis alternativa, y espero que todas las partes interesadas estén familiarizadas y sean conscientes de ello.

Creo que sería bueno tener una opción de compilador para hacer que private transpile a algún tipo de _soft_ privado que se aplicaría en tiempo de ejecución. No creo que el caso de uso de la necesidad de un verdadero hard privado sea especialmente común, por lo que incluso aparte de cualquier disgusto por la sintaxis # , creo que la mayoría de la gente tenderá a quedarse con private . Pero el tiempo de compilación solo privado es _demasiado_ suave en mi opinión. Además, una opción de este tipo ayudaría a reducir la cantidad de posibles variantes de privado ... si los desarrolladores se quedan para implementar esto por su cuenta, entonces podría tener todos estos:

class Demo {
  private a

  #b

  <strong i="9">@reflect</strong>
  #c
}

Así que propongo que con la nueva opción habilitada, private a se transpile a <strong i="13">@reflect</strong> #a , donde @reflect es un decorador que permite la reflexión sobre la propiedad a través de una API respaldada por la comunidad. Se ha hablado de una biblioteca de decoradores estándar, por lo que el decorador @reflect (o como queramos llamarlo) podría estandarizarse en el futuro; Creo que sería un buen candidato para eso.

Supongo que la principal desventaja de mi propuesta sería el impacto en el rendimiento. Podemos esperar que algún día JS tenga algunos decoradores estándar que se implementen de forma nativa para optimizarlos, pero la realidad en el futuro previsible es que <strong i="19">@reflect</strong> #x sería más lento que solo #x . Pero solo propongo esto como una opción, que probablemente debería estar deshabilitada de forma predeterminada (también por razones de compatibilidad con versiones anteriores).

@MichaelTheriot

Más tarde en esto, pero en realidad hay una propuesta que sugiere esta-> sintaxis var.

De acuerdo, es muy probable que esta propuesta esté muerta ("el comité no estaba entusiasmado" es la única razón por la que he podido encontrar)

El comité ha dado muchas razones bien consideradas para respaldar la propuesta actual en lugar de la propuesta de clases 1.1, por ejemplo https://github.com/tc39/proposal-class-fields/issues/100#issuecomment -429460917

@mbrowne

Puede que me lo haya perdido. La página de problemas de las clases 1.1 ha estado inactiva durante medio año, e incluso el ejemplo que vinculó se escribió un mes después de mi comentario.

Para su información, mencioné esto en el hilo que vinculó hace varios meses. Mi comentario aquí fue solo para abordar una idea errónea de que no se ha propuesto una sintaxis alternativa, ya que creo que todas las partes involucradas deben ser conscientes de que ese no es el caso.

Editar: Mi comentario no sugiere que TypeScript haga algo diferente. Creo que es útil corregir la información errónea sobre los temas de referencia de una propuesta.

@MichaelTheriot las partes que necesitan ser informadas de las propuestas alternativas no son las partes involucradas en esta conversación. TypeScript seguirá la propuesta que está en camino de ser ratificada. En mi opinión, el hecho de que se hayan propuesto sintaxis alternativas y no se hayan adoptado no es realmente útil para esta conversación.

Hola chicos, en caso de que ayude, me gustaría compartir mi propia implementación de miembros privados / protegidos en tiempo de ejecución:

Ver lowclass .

Consulte los extensos archivos de prueba que muestran todo tipo de usos de miembros públicos / protegidos / privados en tiempo de ejecución. La implementación no es larga y algunas características se pueden omitir para tener solo la funcionalidad mínima protegida / privada.

Notas:

  • Utiliza WeakMaps para almacenar estado protegido / privado.
  • A diferencia de otras implementaciones que he visto, funciona con código asíncrono con devoluciones de llamada / promesas / espera porque no depende del seguimiento de pila de llamadas sincrónico.
  • Funciona con getters / setters (incluidas super llamadas) (ver pruebas).
  • Funciona con super nativo, o usando un ayudante Super para ES5 (ver pruebas).
  • Admite el método constructor (ver pruebas).
  • Posibilidad de extender las clases integradas (excepto Date, pero quería investigar eso, aunque la gente dice que no es posible, pero quiero confirmarlo. Ver pruebas, fe trabajando con elementos personalizados nativos).
  • Capacidad para extender class es nativos regulares (ver pruebas).
  • envuelve class es nativos, dándoles habilidades protegidas y privadas (ver pruebas).
  • Escriba clases function estilo ES5 en lugar de class es nativas (consulte las pruebas).
  • mucho espacio para las optimizaciones del rendimiento (por ejemplo, almacenar en caché las llamadas de ayuda super / protegidas / privadas y optimizar los algoritmos de búsqueda)

Para ejecutar pruebas:

npm install
npm test

También consulte https://github.com/babel/proposals/issues/12 y https://github.com/babel/babel/issues/8421 para obtener detalles y problemas con la implementación de Babel.

Hola a todos

No implemente la especificación de campos de clase privada aún no finalizados. Tiene problemas.

Por favor lea este hilo .

Animaría a cualquiera que lea esto a que eche un vistazo a otras ideas de sintaxis (solo mire detenidamente, hay más) y exprese sus opiniones.

fe aquí hay otro hilo (con mejores ideas de sintaxis que el actual # mi humilde opinión).


Si hay alguna comunidad de JavaScript que ya use público / privado / protegido ampliamente, es la comunidad de TypeScript la que tiene una gran oportunidad de ayudar a dar forma al futuro de JS privado / protegido.

Entonces, los campos de clases privados se envían en V8 v7.2 y Chrome 72. ¿Hay algún plan para comenzar a implementar la propuesta de campos privados?

@ ChrisBrownie55 Los campos públicos se están enviando. Los privados no lo son.

@jhpratt, eso es mi problema, pero parece que el equipo de Chrome está planeando realizar envíos privados en un futuro cercano.

Para referencia: https://v8.dev/blog/v8-release-72#public -class-fields

Documenta que están enviando campos de clase pública a partir de V8 7.2, pero hay esto con respecto a los campos privados (el énfasis es mío):

El soporte para campos de clases privados está planeado para una futura versión V8 .

@isiahmeadows En realidad, me estaba refiriendo a una publicación diferente en el blog de desarrolladores de Google.

Screenshot of Google Developers page

Conclusión

Los campos de clases públicas se envían en V8 v7.2 y Chrome 72. Planeamos enviar los campos de clases privadas pronto.

Enlace al artículo en el blog de desarrolladores de Google

Estos artículos fueron escritos por @mathiasbynens y Andreas Haas, a quienes puede pedir una aclaración si es necesario (aunque creo que cada una de esas publicaciones fue bastante clara). cc @gsathya y @joyeecheung que están trabajando en los toques finales de la implementación en V8.

De todos modos, la reunión del TC39 de enero de 2019 culminó un año y medio de repensar alternativas a los campos privados y propuestas de métodos con una reafirmación más del consenso sobre las propuestas. Creo que podemos considerar la versión actual estable y lista para usar con TypeScript.

Chrome acaba de lanzar campos de clases privados 🎉
Solo están en Chrome 74 actualmente lanzados en la compilación _canary_.

screenshot of tweet

¡Acabo de enviar campos de clases privadas en Chrome 74! Pruébelo en Chrome Canary hoy mismo.
- Sathya Gunasekaran a través de Twtiter

¿Alguien sabe dónde estamos aquí para elegir una implementación específica (o crear una) para campos de clases privados? Vi que @trusktr recomendaba lowclass pero no sé si "_Private Inheritance_" es parte de la especificación.

Decididamente no lo es; los campos privados no caminan por la cadena del prototipo (porque entonces otros objetos podrían verlos y, por lo tanto, no serían privados)

Asumiría que los campos privados se transferirán a WeakMaps (un WeakMap por campo, de la misma manera que lo hace Babel). También debería haber una opción para mantener la sintaxis # en el resultado final, para aquellos que se dirigen exclusivamente a navegadores que lo admitan (esto será más relevante con el tiempo, por supuesto).

Por razones de rendimiento, también podría valer la pena considerar una opción que permita a los desarrolladores usar la sintaxis # para compatibilidad futura (cuando más navegadores lo admitan), pero en realidad se transpile a propiedades públicas con algún prefijo especial, por ejemplo, __ts# . WeakMaps debería ser comparado para ver si esto es realmente necesario, pero sospecho que la diferencia de rendimiento entre las propiedades públicas y WeakMaps podría ser significativa. Si se agregara una opción de este tipo, debería estar desactivada de forma predeterminada, por supuesto, ya que los desarrolladores que usan la sintaxis # normalmente esperarían que sea privada tanto en tiempo de compilación como en tiempo de ejecución. Pero para aquellos que desean maximizar el rendimiento en tiempo de ejecución y están satisfechos con solo el tiempo de compilación privado mientras tanto, podría ser una buena manera de comenzar a usar la nueva sintaxis sin causar potencialmente una degradación del rendimiento.

¿Alguna actualización sobre el progreso de la implementación? ¿Quizás un PR que podamos construir para probar y proporcionar comentarios?

@jhpratt seguro! Si revisa la rama en este PR , podrá probar los campos de instancia con nombre privado. Los métodos y los accesos están en curso.

Esperamos impulsar este trabajo. Podemos PR los cambios contra este repositorio (Microsoft / TypeScript) tan pronto como este PR prerrequisito se fusione: https://github.com/Microsoft/TypeScript/pull/30467.

Los comentarios son bienvenidos.

No sé si la "herencia privada" es parte de la especificación.

Nota al margen, planeo eliminar esa función en clase baja, para permitir una privacidad real del 100%. Realmente no lo he necesitado en la práctica, fue más un experimento.

Por cierto, tengo ganas de publicar aquí, en caso de que cualquier teoría sobre la "herencia privada" pueda ser de alguna utilidad (tal vez simplemente interesante, o tal vez ayude a generar otras ideas):


en caso de que te interese:

"Herencia privada" (como se ve en la versión actual de lowclass) significa que una subclase puede usar métodos privados heredados de una superclase, pero el método aplica cambios _ solo _ a las propiedades privadas de la instancia _ dentro del alcance de esa subclase_, como si la subclase tenía esos métodos definidos como métodos privados en su propia definición, pero la subclase no puede modificar las propiedades privadas de la instancia en un ámbito de clase superior o hermana.

En comparación, en la "herencia protegida" una subclase _ puede_ modificar las propiedades de su propia instancia o instancia de superclase, pero aún no puede modificar las propiedades de una clase hermana. En la herencia protegida, una subclase modifica las propiedades que todas las superclases pueden ver (todas las superclases leen / escriben en esas mismas propiedades).

En otras palabras, en el concepto de "herencia privada" cada clase tiene un alcance privado, y cualquier método privado heredado solo opera en el alcance de la clase local, en contraste con los métodos protegidos donde los métodos protegidos operan en un solo alcance para toda la jerarquía de clases.

No estoy seguro de si eso tiene mucho sentido, así que aquí hay ejemplos de código simples para explicar a qué sería similar la "herencia privada", si lo escribiéramos usando las características actuales de campo privado de campos de clase de propuesta de ecma:


El código de ejemplo es más fácil de entender:

No hay "herencia privada" en los campos de clase de propuesta, por lo que lo siguiente no funcionará (y estoy de acuerdo en que esto es deseable para mantener la verdadera privacidad):

class Foo {
    test() {
        this.#privateMethod()
    }

    #foo = 'foo'

    #privateMethod() {
        console.log(this.#foo)
    }
}

class Bar extends Foo {
    test() {
        // This does not work, no private inheritance:
        this.#privateMethod()
    }

    // #foo is private only inside Bar code, it is NOT the same #foo as in Foo
    // scope.
    #foo = 'bar'
}

En clase baja, "herencia privada" sería equivalente a escribir el siguiente código no DRY para emular lo mismo, usando algo de copiar / pegar en su editor:

class Foo {
    test() {
        this.#privateMethod()
    }

    #foo = 'foo'

    #privateMethod() {
        console.log(this.#foo)
    }
}

class Bar extends Foo {
    test() {
        // This does not work, no private inheritance:
        this.#privateMethod()
    }

    // #foo is private only inside Bar code, it is NOT the same #foo as in Foo
    // scope.
    #foo = 'bar'

    // copy the method over by hand (because there's no private inheritance):
    #privateMethod() {
        console.log(this.#foo)
    }
}

En ambos ejemplos, la variable #foo es una variable específica para cada clase. Hay dos variables #foo , no una; cada uno legible y escribible solo por código en la misma definición de clase.

En lowclass, herencia privada nos permite volver a utilizar métodos de superclase privada, _but_ el método funciona en el ámbito donde se utilice el método. Así que termina siendo como si hubiéramos copiado y pegado el método de superclase en la subclase, como en el ejemplo anterior, pero todavía hay dos variables #foo separadas para cada clase.

En lowclass, si #someMethod se utiliza en la superclase, que opera en el #foo de la superclase. Si se usa #someMethod en el alcance de la subclase, ¡opera en el #foo de la subclase, no en el #foo de la superclase!

Espero que eso explique el concepto, e incluso si no se usa, espero que sea interesante o útil para generar ideas de cualquier tipo.

Ahora está en el canal estable de Chrome, por lo que los desarrolladores pueden usarlo de forma nativa. Estoy principalmente interesado en este problema debido a VSCode: al escribir vanilla .js javascript, VSCode lo marca como un error. ¿Hay alguna manera de agregar soporte para campos de clases privados en Vanilla JS en VSCode por separado del debate sobre si agregarlos a Typecript?

Personalmente, no creo que TS deba agregar soporte para ellos antes de llegar a la etapa 4. TS ya tiene privado en tiempo de compilación que funciona lo suficientemente bien por ahora. Después de que llegue a la etapa 4, estaría de acuerdo en que tiene sentido. (También ha habido episodios ocasionales de cambio en la discusión, por lo que todavía no lo consideraría listo para el horario de máxima audiencia).

Actualización: también es compatible con el Nodo 12 estable. Además, Babel tiene un complemento para transformar esta sintaxis. Los desarrolladores suelen utilizar funciones antes de que se conviertan en propuestas de la etapa 4. Me gustaría ver soporte agregado para esta sintaxis en Vanilla JS (non-ts) o una forma de habilitarlo a través de jsconfig.json para que VSCode no muestre un error al usarlos. El repositorio de VSCode dice que su compatibilidad con JS está respaldada por TypeScript y se refiere a este problema.

Debo decir que no tiene sentido que TypeScript no admita la función en absoluto, ya que ya existe en producción en un navegador importante y Node. Esto no quiere decir que TypeScript tenga que solidificar por completo todo en este momento y lanzarlo como una función predeterminada.

Sugeriría que TypeScript introduzca campos privados bajo una marca que indique que esta función es experimental y está sujeta a cambios entre la etapa 3 y la etapa 4.

¿Quizás podríamos implementar el soporte de sintaxis primero sin semántica?

¿Quizás podríamos implementar el soporte de sintaxis primero sin semántica?

Para la verificación de tipos / intellisense, creo que debe haber algún tipo de semántica, pero no puede tener soporte de transformación de nivel inferior como BigInt (solo se puede usar con esnext ).

fwiw, solo está sujeto a cambios en la etapa 3 debido a los comentarios de implementación. Dado que Chrome lo está enviando, cualquier cambio es muy poco probable.

@ ChrisBrownie55 diría que no tiene ningún sentido que esta función aún no esté implementada

Parece que esto está en progreso:
https://github.com/microsoft/TypeScript/pull/30829
(que aparentemente está esperando en https://github.com/microsoft/TypeScript/pull/30467)

Correcto, # 30829 está listo para fusionarse después de rebase, módulo algunas funciones de activación que tal vez queramos hacer para que explote en métodos con nombres privados.

Chicos, solo porque un navegador importante implementó la función (para ver cómo se siente, jugar con ella, etc.) no significa que todos deberían hacerlo.

También ha habido episodios ocasionales de cambio en la discusión, por lo que todavía no lo consideraría listo para el horario de máxima audiencia.

Como mencionó @isiahmeadows , la propuesta de los campos de clase está llena de controversia y a muchas personas no les gusta. Aquí hay un par de problemas que muestran que a la comunidad no le agradan los campos privados actuales:

Si fuera un implementador del lenguaje, me preocuparía por esto, y no me gustaría ser responsable de que se publique una característica que no me gusta mucho (grabada en piedra) porque decidí permitir que miles de desarrolladores (sin saberlo) comenzaran a usar un problema característica en el código de producción.

Los campos privados es quizás la más controvertida de todas las características introducidas desde ES6. Creo que sería prudente que un implementador del lenguaje tuviera en cuenta el desagrado antes de ayudar a establecer la característica en piedra.

@trusktr Puede ser una característica controvertida, pero si los desarrolladores la usan debería ser una decisión que se deja en manos del desarrollador, no de las herramientas. Un navegador importante lo ha enviado no para "jugar con él", sino para enviarlo para su uso en producción. También se ha enviado en Node, el tiempo de ejecución JS del lado del servidor más popular. Nuevamente, me preocupa menos si la sintaxis llega a TypeScript o no, pero me preocupa más si la sintaxis es compatible con el servidor de lenguaje JavaScript en VSCode (que está respaldado por TypeScript).

También se ha enviado en Node

Solo como efecto secundario de la versión de Chrome, que mantiene el motor JS de Node.

Puede ser una característica controvertida, pero si los desarrolladores la usan debe ser una decisión que se deje al desarrollador, no a las herramientas.

Ese puede ser el caso de desarrolladores como usted (tal vez solo necesite lanzar un producto y trabajará con cualquier herramienta que tenga, que es de hecho lo que debe hacer en ese sentido, y lo que hacen muchos desarrolladores empleados).

También hay muchos desarrolladores que pueden no saber acerca de las pistolas asociadas con los campos de clase, mientras solo intentan usar las herramientas que se les proporcionan.

Y también hay desarrolladores que se preocupan por el lenguaje en sí y el futuro del código mantenible, y les gustaría verlo evolucionar correctamente, antes de que ciertos errores sean demasiado tarde para deshacerse.

Lo bueno es que, debido a que los nuevos campos privados usan la sintaxis # , todavía hay espacio para arreglarlo usando la palabra clave private como alternativa.

¿TS realmente tiene que seguir el estándar al 100%? Ya sabemos que el comité va en contra de la comunidad con thisGlobal o #privateLol , así que tal vez sea hora de decir que Google no tiene el monopolio de JavaScript antes de que sea demasiado tarde.

@TeoTN Los campos privados no son cosa de Google. Ha procedido a través de TC39, al igual que todos los demás estándares recientes.

Algunos puntos para ayudar a proporcionar claridad:

  • No tenemos prisa por enviar funciones de ES que aún no están completamente preparadas (consulte también: encadenamiento opcional, fusión nula, expresiones de lanzamiento, operador de canalización, nombre de, etc.)
  • Por el contrario, la implementación de funciones ES ratificadas y de envío no es opcional
  • A mucha gente no le gustan ciertas cosas no es un factor de ninguna manera
  • Los campos privados estarán en TS cuando creemos que es seguro para nosotros implementarlos sin cambios de diseño posteriores (o revocaciones) que causen serios problemas al usuario.

@RyanCavanaugh ¡ Gracias por la aclaración y también por todo el increíble trabajo! Una pequeña sugerencia: los ES están evolucionando continuamente y hay muchas características en las que se está trabajando, creo que es bueno tener una regla que indique en qué etapa: ¿Etapa 4? ¿Etapa 3? o en algún lugar intermedio? - Las funciones de ES son elegibles para su inclusión. De lo contrario, este tipo de discusión podría repetirse una y otra vez en el futuro para otras características.

Se puede decir razonablemente que los campos privados están completamente horneados.

@kkimdev La etapa 4 es lo más lejos posible; significa haberse convertido en parte del estándar.

Funciones de ES que no están completamente horneadas

Curioso, ¿qué son las funciones ES totalmente horneadas? ¿Qué significa "completamente horneado" en este ejemplo?

La implementación de características ES ratificadas y de envío no es opcional.

Eso es totalmente razonable considerando el objetivo de TypeScript de ser simplemente tipos sobre Vanilla JS (por lo que cosas como namespace fueron una mala elección con respecto a los objetivos actuales, y enum es discutible).

TypeScript tiene cierto poder para ayudar (o no ayudar) a la comunidad a cambiar las especificaciones del lenguaje, al esperar (o no esperar) para enviar una función hasta que todos los motores principales hayan enviado por unanimidad la función dada.

Parece ineficiente, ya que los miembros del equipo de TS se sientan en TC39, por lo que ya han sido parte del consenso para que una característica sea la etapa 3 antes de que alguien la haya enviado en primer lugar, esta incluida.

Realmente valoro las decisiones de diseño de TypeScript por ser conservadoras en lo que envían; en muchos casos, tiene sentido esperar un poco más para dar estabilidad garantizada a los desarrolladores. Estoy muy contento con las decisiones de política con respecto a los campos privados y en contacto frecuente con @DanielRosenwasser sobre ellas. El equipo de TypeScript ha brindado muchos comentarios útiles a TC39 a lo largo de los años, lo que ayudó a dar forma al diseño de muchas funciones.

Creo que el mejor lugar para discutir estas decisiones de diseño de lenguaje sería en los repositorios de propuestas, en las reuniones del TC39 y en otros contextos dedicados a este trabajo. Hemos discutido ampliamente las propuestas de métodos y campos privados con @trusktr allí; la discusión aquí parece fuera de tema.

En última instancia, creo que TC39 es el lugar donde deberíamos continuar haciendo el diseño del lenguaje, y el repositorio de TypeScript podría ser un lugar para discutir otros aspectos, como la prioridad y los detalles de implementación de una función, y el juicio de cuándo se está ejecutando una función. lo suficientemente estable para enviar.

Dado que TypeScript Intellisense potencia el resaltado de sintaxis de JavaScript en VS Code y los dos problemas de resaltado de sintaxis que encontré (Microsoft / vscode # 72867 y Microsoft / vscode # 39703) en la redirección del repositorio de VS Code aquí, donde se discute la implementación de esto en TypeScript - permítanme contribuir diciendo que sería genial que esto no sea un error en los archivos JavaScript.

JavaScript perfectamente válido se marca como erróneo en VS Code porque un compilador para un lenguaje diferente está en proceso de decidir si la sintaxis será compatible o no. :-)

No tengo ningún problema con que TypeScript se tome su tiempo antes de tomar una decisión al respecto (¡de hecho lo apoyo!), Pero esto afecta el resaltado de sintaxis de JavaScript de una manera que no se puede arreglar fácilmente ni trabajar incluso localmente (en la medida en que Lo sé) parcheando el archivo de gramática del resaltador de sintaxis, porque no hay ninguno para parchear (AFAIK).

Si bien no estoy en el equipo de TypeScript, están trabajando activamente para implementar esto y no creo que haya muchas dudas en este momento de que se admitirán los campos privados. Consulte https://github.com/microsoft/TypeScript/pull/30829.

Puedo confirmar que se está trabajando en ello: estamos colaborando con el equipo de TS y actualmente estamos terminando una nueva base. Emocionado por los campos con nombres privados en TS (y, por extensión, Language Server).

¡Muchas gracias a nuestros colaboradores en Bloomberg por implementar esto en https://github.com/microsoft/TypeScript/pull/30829!

Hola. Si desea que cree un problema separado para esto, dígalo. Estoy interesado en saber cuál es la justificación para emitir el #private PropertyDeclaration que condujo a este problema .

Por ejemplo, se generarán las siguientes declaraciones:

// index.d.ts
declare class Foo {
    #private;
    // ...
}

... Dada la entrada:

// index.ts
class Foo {
    #name: string;
}

Primero trato de entender por qué debe estar allí, pero también si se puede omitir, dado que estoy construyendo herramientas en torno a la generación de declaraciones.

Primero trato de entender por qué debe estar allí, pero también si se puede omitir, dado que estoy construyendo herramientas en torno a la generación de declaraciones.

La presencia de un privado hace que la clase sea nominal en nuestro análisis, por lo que es importante preservarlo en un archivo de declaración. ¿Quizás podría usar una herramienta de transformación de declaración posterior a la emisión como dts-downlevel para bajar de nivel la declaración privada para TS más antiguos de alguna manera? (Todavía no sé si tiene un nivel inferior para #privados)

Para agregar a lo que dijo Wesley: downlevel-dts convierte #private en private modifier, para compatibilidad con versiones anteriores de TypeScript.

La presencia de un privado hace que la clase sea nominal en nuestro análisis, por lo que es importante preservarlo en un archivo de declaración

¿Puede explicar cómo hace que la clase sea nominal? 🙂 Dadas varias propiedades privadas, #foo y #bar , solo se agregará una declaración ambiental especial #private a las declaraciones. No hay forma de analizar a partir de las declaraciones ni cuáles eran los nombres de las propiedades privadas ni cuántas había, porque todas se reemplazan con una única declaración de propiedad #private . Lo entendería mejor si conservara los nombres #foo y #bar . Es un poco extraño, especialmente dado que LanguageService se queja de que la propiedad #private nunca se usa. Me parece un error. Pero bajo todas las circunstancias, los campos privados no son parte de las propiedades públicas del tipo y no son accesibles desde fuera de la clase, así que teóricamente no veo por qué necesitan ser parte de las declaraciones. ¿No deberían aplicarse los mismos principios que para los campos y métodos anotados con otros modificadores de acceso distintos de public en los que no son un KeyOf el tipo y no forman parte de las declaraciones ambientales?

Para agregar a lo que dijo Wesley: downlevel-dts convierte #private en private modifier, para compatibilidad con versiones anteriores de TypeScript.

Suena como una buena solución. Sin embargo, al hacer eso, cualquier propiedad que le esté dando al modificador private no será parte del archivo .d.ts dado que no forma parte de las propiedades públicas del tipo. Estoy específicamente interesado en las declaraciones, que incluso con los ejemplos más simples generan diagnósticos para una propiedad no utilizada llamada #private .

@wessberg Informé el error que notó en las advertencias del servicio de lenguaje no deseado y probablemente pueda implementar una solución.

Re tu otra pregunta:

¿Puede explicar cómo hace que la clase sea nominal?

Alguien abrió un problema sobre eso antes .

Una razón para hacer algo nominal en estos casos es para que el implementador de la clase pueda mantener algún invariante oculto entre los campos privados: hacer que los tipos sean estructurales socavaría este objetivo al menos sin tipos realmente sofisticados que puedan expresar cosas como "la lista es siempre ordenados "o" el diámetro es 2 * el radio ".

Otra razón es que el código como el siguiente debería fallar en la verificación de tipo, ya que no hay forma de que "haga lo correcto" en tiempo de ejecución:

class A {
    #foo = getFoo();
    bar = "bar";
    equals(other: A) {
        return this.#foo === other.#foo && this.bar === other.bar;
    }
}

new A().equals({ bar: "bar" }); // error: missing property '#foo'

Hola amigos, estoy tan emocionado de tener la sintaxis #private ! ¡es impresionante!

pero debo admitir que estoy realmente molesto porque no tenemos sintaxis taquigráfica (ver propuesta) , así:

class Counter {
  #count = 0
  increment() {
    return #count++
  }
}

Me preguntaba: ¿podríamos desarrollar un complemento de mecanografiado o una opción tsconfig para habilitar la sintaxis taquigráfica como característica experimental?

Me muero por la hábil mejora ergonómica, para evitar tantas repeticiones innecesarias de this. : las desventajas de la sintaxis taquigráfica, como se indica en la propuesta, no parecen ser preocupaciones importantes de las que preocuparme, así que ciertamente estaría feliz de configurar "experimentalPrivateShorthand": true o algo así en mis propios proyectos

¿Se puede hacer esto? tal vez haya una buena razón por la que no es posible? cual seria el trabajo involucrado? ¡salud!

: ola: persecución

@ chase-moskal TypeScript no implementa nada aparte de los tipos más allá del estándar ECMAScript. La razón de esto es el cambio de semántica, como lo demuestran los decoradores y los campos privados.

@ chase-moskal La forma más práctica de evitar escribir this todo el tiempo es, honestamente, simplemente asignarle un atajo en su IDE (como F3, por ejemplo). Muchas cosas son posibles bifurcando el analizador TS o el analizador Babel y escribiendo complementos, pero son mucho trabajo y lo desincronizarían con las herramientas oficiales. Me doy cuenta de que su pregunta era sobre el apoyo oficial, por supuesto, solo pensé en compartir mis pensamientos.

@jhpratt - texto mecanografiado utilizado para ayudarme a mantenerme a la moda. ¡Me dio decoradores y funciones de flecha en la antigüedad! solía ser competitivo con babel, al menos más que ahora

Honestamente, estoy realmente jelly-belly y no puedo escribir magníficas clases minimalistas como lo hicieron mis contrapartes que usan babel hace más de un año, ¡y Babel incluso tiene todas las campanas y silbatos que estoy añorando!


@mbrowne : no es realmente la "capacidad de escritura" del código lo que importa tanto como la legibilidad , así que no nos preocupemos por contar las pulsaciones de teclas. mi punto es que javascript this repetición es con demasiada frecuencia un desorden superfluo e indigno

ahora piense en esto para mejorar la legibilidad: cuando obtenemos la sintaxis abreviada #private , cada vez que vea this , instantáneamente sabrá que fue para acceder a un miembro público, una gran ganancia para ¡legibilidad!


de todos modos, acabo de descubrir que el mecanografiado aún no admite métodos privados

así que todo esto solo necesita más trabajo y tiempo, aparentemente de la gente de Bloomberg

sin métodos privados para hacer coincidir los campos, solo tenemos que esperar (¡porque nadie mezclaría mecanografiado-privados con hashtag-privados en la misma clase sin volverse loco!)

Entonces, ¿es el equipo de Bloomberg la que moderniza el mecanografiado aquí, y también estuvieron involucrados en las mismas características de privacidad para babel hace un año también? Están haciendo el trabajo de Dios, ¡y tengo curiosidad por saber por qué! ¡Seguid así! ¡salud!

: ola: persecución

Sí, TypeScript te dio decoradores hace años. ¿Adivina qué? La semántica cambió, a lo grande. Ahora TypeScript no admite la API heredada en el futuro cercano, y causará roturas masivas cada vez que se decida eliminarlo. Las funciones de flecha son parte de la especificación ECMAScript, por lo que mencionarlas es completamente irrelevante.

TypeScript no implementa actualmente ninguna propuesta de ECMAScript antes de llegar a la etapa 3. Ahí es donde necesitaría obtener la abreviatura antes de que TS esté interesado.

Sí, TypeScript te dio decoradores hace años. ¿Adivina qué? La semántica cambió, a lo grande.

Vivimos en un mundo que no es ideal, y ahora se necesitan algunas características. Por ejemplo, la propuesta de los decoradores aún se encuentra en la etapa 2, pero algunos grandes proyectos (Angular) los usan activamente durante mucho tiempo. Otro ejemplo: ECMAScript no especifica modificadores protected para los miembros de la clase, lo cual es útil para resolver problemas reales.

Ahora TypeScript no admite la API heredada en el futuro cercano, y causará roturas masivas cada vez que se decida eliminarlo.

Otros lenguajes también introducen características experimentales en las banderas del compilador.

No digo que TypeScript deba implementar cada propuesta en la Etapa 1 o 2, pero muchas propuestas interesantes para TS simplemente se atascaron, porque no hay equivalentes en ECMAScript, por ejemplo, https://github.com/microsoft/TypeScript/issues/2000

@ikokostya Estaba usando decoradores como un ejemplo de algo donde la semántica ha cambiado después de que TypeScript los implementó. ¿Realmente estás diciendo que esta taquigrafía es "necesaria ahora mismo"? Créame, podemos administrar los cinco personajes adicionales. Si es tan importante para usted, puede bifurcar el compilador.

TypeScript se ha mostrado firme en no implementar nada antes de la etapa 3, incluso bajo una bandera. Esto se ha discutido a fondo en varios otros temas anteriormente.

No veo nada más que dar vueltas, así que no responderé más a menos que surja algo notable.

@jhpratt Mi punto no se trata de taquigrafía. Por favor lea mi comentario.

La sugerencia sobre la bifurcación es absolutamente irrelevante.

No todo el mundo está de acuerdo, y más concretamente, no todo el mundo en el comité TC39 está de acuerdo en que la abreviatura haría que el código fuera más legible o intuitivo. Hubo mucha discusión sobre esto, y la sintaxis abreviada se movió a una propuesta separada debido a esas preocupaciones. (No lo he pensado lo suficiente como para formarme una opinión propia, simplemente dando un resumen). Si desea impulsar esta propuesta, la forma de proceder es proporcionar comentarios al TC39. Estoy seguro de que ya hay mucho trabajo involucrado en el mantenimiento de TS y la implementación de todas las propuestas que han alcanzado la etapa 3, por lo que es difícil imaginar que esto se considere para TS a menos que avance más en TC39.

pero debo admitir que estoy realmente molesto porque no tenemos sintaxis taquigráfica (ver propuesta)

Esa abreviatura sería incompatible con la propuesta de canalización que también podría usar # y ya se discutió para convertirse en una propuesta de etapa 2. Realmente no tiene sentido implementar propuestas tan pronto y luego hacer cambios importantes. En una etapa tan temprana, ni siquiera sabe qué propuesta ganará.

Incluso si resulta ser compatible, puedo pensar en al menos algunos casos de uso más para un operador de prefijo # que son más útiles que ser una forma abreviada de escribir 5 caracteres adicionales.

... especialmente cuando una buena parte del caso de uso para campos privados no está en this en absoluto (por ejemplo, static isMe(obj) { try { obj.#x; return true; } catch { return false; } } , por nombrar un ejemplo).

@phaux : es muy buena información sobre taquigrafía vs canalización, ¡gracias!

@jhpratt

TypeScript se ha mostrado firme en no implementar nada antes de la etapa 3, incluso bajo una bandera.

bastante justo, pero luego debe señalarse, que los métodos privados están de hecho en la etapa 3 , pero aún no hay soporte de mecanografiado, y mire, me gusta mucho la propuesta de taquigrafía, pero eso es solo estético, en realidad estoy ahora mucho más molesto por la falta de métodos privados y accesos en este momento

Supongo (rezo) que el equipo de Bloomberg continúe el trabajo de Dios aquí en mecanografiado, como lo hicieron para Babel hace un año. si es así, entonces realmente tenemos que ser pacientes y sentarnos tranquilos :)

Me parece que el mecanografiado solía ser mucho más competitivo con babel y los navegadores para las funciones de ecmascript, y ahora es demasiado conservador: estamos en una situación en la que tanto babel como chrome habían enviado campos privados (sin marcar) durante un año antes Bloomberg vino a salvarnos

Estoy incómodo por la creciente divergencia entre el mecanografiado y el conjunto de características de babel: mis amigos de babel han estado escribiendo código maravillosamente hábil durante el último año, mientras que yo todavía estoy aquí pagando una multa por mecanografiado, ¡se están riendo de mí!

Me encantó ese texto mecanografiado que solía ofrecer indicadores experimentales que me permitían decidir qué estoy dispuesto a arriesgarme a refactorizar en el futuro para comprarme algunas funciones geniales: ¿es ahora la posición del mecanografiado, que es demasiado peligroso dejar que los desarrolladores decidan esos riesgos, y ¿Ese texto mecanografiado es ahora mi niñera?

Cada vez más, parece que puedo elegir funciones increíbles o tipos estáticos, pero ahora no puedo tener lo mejor de ambos mundos, por lo que hay una disonancia cognitiva creciente dentro de mí.

Tengo mucha curiosidad acerca de la dinámica aquí: si Bloomberg no interviniera como un caballero con una armadura brillante, ¿cuánto tiempo habría pasado antes de que el mecanografiado aceptara el desafío? ¿O es un experimento mecanografiado: "si simplemente evitamos estas nuevas características ... cuánto tiempo antes de que la comunidad simplemente ... lo haga por nosotros?", ja, ¡eso es bastante cínico incluso para mí! ¿O tal vez esta es una colaboración benévola realmente genial que explora nuevas vías de financiamiento y soporte para el código abierto, y ha sido un poco más lento de lo esperado? ¿O quizás la filosofía mecanografiada es mucho más conservadora de lo que solía ser? ¿Dónde estamos en este espectro?

para implementar las características de la etapa 3, ¿es más que el mecanografiado carece de ancho de banda o de prioridad?

Lo siento por despotricar, y oye, realmente no estoy tratando de ser grosero o presentar acusaciones serias aquí, solo estoy lanzando pensamientos desde mi perspectiva ajena. Solo soy un usuario y siento curiosidad genuina por saber cómo reaccionarían las personas aquí más informadas a estas imágenes que he pintado. Discusión interesante, ¡los agradezco a todos!

: ola: persecución

Me encantó ese texto mecanografiado que solía ofrecer indicadores experimentales que me permitían decidir qué estoy dispuesto a arriesgarme a refactorizar en el futuro para comprarme algunas funciones geniales: ¿es ahora la posición del mecanografiado, que es demasiado peligroso dejar que los desarrolladores decidan esos riesgos, y ¿Ese texto mecanografiado es ahora mi niñera?

No se trata de niñera. Se trata de no querer perder tiempo implementando características que inevitablemente se convertirán en una carga de mantenimiento cuando la semántica cambie en la propuesta. Absolutamente no quieren perder tiempo averiguando cómo reconciliarse con la semántica cambiada cuando están en conflicto con la implementación de TS. Tienen mejores cosas que hacer. Todavía hay una montaña de problemas relacionados con los tipos que resolver, por lo que tiene sentido gastar sus recursos limitados en eso y no intentar hacer el trabajo de TC39 además de resolver los problemas del sistema de tipos.

En cuanto a los métodos de acceso privados y los accesos: tampoco están implementados en V8. Los métodos de clase y los campos de instancia son diferentes, y no pueden simplemente ... activar un interruptor para admitirlos también. Se necesita tiempo real para implementarlos y ya tienen las manos ocupadas con el trabajo tal como está y son un equipo pequeño. Además, la regla no es solo que la propuesta debe estar en la etapa 3: también dicen explícitamente que quieren tener una gran confianza en la semántica de la propuesta para que sea definitiva. Aunque es poco común, la semántica _puede_ cambiar en la Etapa 3. La característica no está implementada en V8 sin una buena razón. Sin embargo, no me malinterpretes; A mí también me encantaría ver implementada esa propuesta y no puedo esperar para usarla. Sin embargo, implementar propuestas de etapas anteriores es una pérdida de tiempo y es mejor invertir el tiempo del equipo de TS en otra parte. Hay innumerables propuestas de Etapa 2, 1 y 0 que me encantaría usar hoy, pero entiendo por qué no puedo tenerlas todavía. Paciencia mi amigo.

También puede usar babel, exclusivamente, para transpilar su texto mecanografiado, si prefiere las opciones que babel pone a su disposición.

@ 0kku , por lo que está diciendo que es solo un problema de ancho de banda / capacidad, en lugar de uno filosófico: la acumulación de errores ahora es una prioridad más alta que la implementación de las características de la etapa 3, sin embargo, en la historia anterior de mecanografiado, tal vez tenía menos errores , por lo que fue más fácil asignar capacidad a implementaciones experimentales? Puedo comprar esta teoría, y nuestra respuesta debería ser esperar o contribuir

@ljharb - oh, eso es muy interesante - ¿es realmente posible ejecutar mecanografiado y babel juntos de esa manera? para lograr lo mejor de ambos mundos?

pero simplemente no puedo ver cómo el servicio de idioma vscode ts podría funcionar sin implosionar en la sintaxis desconocida (como los métodos privados, por ejemplo). la falta de intellisense muerde una parte demasiado grande de la propuesta de valor del mecanografiado: si intellisense tiene que desactivarse por completo, la estrategia es inútil

¿Cómo podría solucionarse esto a largo plazo? Supongo que si distinguimos errores de mecanografiado específicos para la sintaxis de cada característica experimental, y también, si un proyecto de mecanografiado pudiera deshabilitar esos errores específicos en el nivel tsconfig, entonces tendríamos una oportunidad de abrir la puerta para aprovechar tanto las características de babel como las características de mecanografiado. al mismo tiempo, hombre, eso sería realmente genial y acabaría con toda la clase de quejas ... ¡salud!

: ola: persecución

@ljharb

También puede usar babel, exclusivamente, para transpilar su texto mecanografiado

Supongo que podría configurar un proceso de verificación de tipos en el que transpile solo los métodos privados usando Babel (pero deje los tipos en todo lo demás) y verifique ese código con tsc . (La secuencia de comandos de compilación, después de pasar la verificación de tipos, solo usaría Babel). Pero tendrías que ignorar muchos errores de sintaxis en tu IDE; creo que eso sería un factor decisivo para la mayoría de las personas.

@ chase-moskal Aunque lo que dijo @ 0kku es correcto en general, no he visto ninguna razón para no implementar métodos privados en TS en este momento. Creo que es más que esa propuesta llegó a la etapa 3 más tarde que los campos de clase, y los implementadores todavía están trabajando en ello.

Si tiene curiosidad por saber por qué no estamos interesados ​​en aprovechar las funciones experimentales, consulte la --useDefineForClassFields . Implementamos inicializadores de propiedades de clase muy, muy temprano, bajo el supuesto de que ninguna propuesta TC39 posible con semántica diferente podría existir de manera plausible, y estábamos bastante equivocados.

Los decoradores tienden a estar en el mismo barco, y te sorprenderá si crees que podemos abandonar por completo el apoyo a la antigua semántica. Varias grandes empresas han creado grandes marcos bien adoptados a su alrededor; es totalmente irreal que pudiéramos decir "Bueno, el nombre de la bandera comenzó con experimental por lo que debería haber sabido que esta función admitida durante los últimos 5 años podría desaparecer un día".

Para ambas características, nos quedaremos atrapados manteniendo dos rutas de código sutilmente diferentes aquí por el resto de nuestras vidas, y apesta, pero esa es la compensación: estamos muy comprometidos con mantener TypeScript de compilación a compilación. actualizaciones posibles sin romper el comportamiento en tiempo de ejecución de su código; esta compensación es invisible cuando está a su favor (por ejemplo, su programa sigue funcionando ), pero puede ver la desventaja en términos de adopción de funciones con más facilidad.

Desde nuestra perspectiva, no puede renunciar a la compatibilidad de tiempo de ejecución de versión a versión, de la misma manera que no puede renunciar a la responsabilidad por negligencia.

También postergamos la adopción anticipada del encadenamiento opcional a pesar del rechazo MASIVO de la comunidad: si tuviera una moneda de cinco centavos por cada vez que alguien dijera "Bueno, ponlo detrás de una bandera", estaría escribiendo esto desde un barco. Pero fue lo correcto, porque hubiéramos tenido que adivinar lo que (null)?.prop produjo, y hubiéramos adivinado absolutamente null (no undefined ), y nosotros ' Estaría viviendo con otra carga de complejidad continua para resolver eso. Hay una fuerte ventaja contrafactual aquí por el hecho de que nadie está atrapado sentado en una base de código de 3 millones de líneas llenas de uso de ?. donde dependen de que produzca null veces, sin forma de incluso averigüe cómo hacer la transición hacia adelante a los diferentes comportamientos undefined .

Bloomberg implementó campos privados porque estaban muy emocionados de tener la función y estaban ansiosos por contribuir a TypeScript. Si no hubieran estado en esta situación, habríamos implementado la función nosotros mismos, como todo lo demás.

En general, diría que la línea de tiempo de JavaScript es muy, muy larga y que, de manera realista, puede escribir JavaScript bueno y ergonómico en 2020 sin usar la sintaxis de 2024, al igual que podría escribir JS bueno y ergonómico en 2016 sin usar la sintaxis de 2020. Nadie está bloqueado por la incapacidad de usar una sintaxis que ni siquiera tiene una semántica finalmente decidida todavía; es solo programación imaginaria en ese momento.

No solo eso, sino que ni siquiera es 100% seguro de que la propuesta de campos de clase actual y todos sus detalles lleguen a la etapa 4 en su forma actual (especialmente ahora que hay una empresa miembro de TC39 que agita para descartar la propuesta por completo y reemplazarla con uno diferente). Supongo que hay un 95% de certeza, pero en general, incluso la implementación de una propuesta de la etapa 3 no está completamente libre de riesgos. Sin embargo, la probabilidad de que se produzcan más cambios después de la etapa 3 es muy baja, por lo que creo que la política actual de TS es buena.

ahora que hay una empresa miembro del TC39 que se esfuerza por descartar la propuesta de [campos de clase] por completo y reemplazarla por otra diferente

Interesante, ¿señalar un enlace a eso?


Aquí hay una idea: tal vez el equipo de TS podría dedicar algo de tiempo a mejorar el sistema de complementos, para brindarles a los autores de complementos una API clara que se conecte tanto al tiempo de compilación como al tiempo de intellisense del protocolo del servidor de idiomas. Esto haría posible que terceros implementen cualquier característica experimental que deseen, incluida una nueva sintaxis, y aún tengan intellisense funcional dentro de los IDE y editores de texto.

La última vez que verifiqué, ttypescript es la única forma de configurar transformadores TypeScript de forma no programática en tsconfig.json , y no se conecta a la inteligencia de ningún IDE, por lo que la capacidad de terceros para crear características significativas que se integran bien con las herramientas existentes como VS Code aún no están disponibles. No querríamos renunciar a nuestra agradable experiencia de VS Code cambiando a ttypescript y necesitando depender de la salida del terminal mientras VS Code no puede comprender la sintaxis y arrojar errores.

Entonces, TypeScript podría centrarse en las funciones estables y permitir que terceros creen o usen funciones experimentales arriesgadas (tan fácil como en el ecosistema de Babel).

Interesante, ¿señalar un enlace a eso?

https://github.com/microsoft/TypeScript/pull/30829#issuecomment -541338266

Hay un conjunto muy limitado de cosas sintácticas que puede hacer con un complemento de Babel; Básicamente, el analizador ya tiene que admitirlo. El "complemento" de expresión do , por ejemplo, aún requiere lógica en el núcleo de Babel: https://github.com/babel/babel/blob/master/packages/babel-parser/src/parser /expression.js#L991 Realmente no es diferente de un cambio de línea de comandos.

¿Hay algún problema que se pueda seguir para los métodos de acceso y las clases privadas?

@RyanCavanaugh

Para ambas características, estaremos estancados manteniendo dos rutas de código sutilmente diferentes aquí por el resto de nuestras vidas.

No creo que deba ser así y puedo imaginar que duele a toda la comunidad. Si los decoradores alcanzan la etapa 3, creo que es razonable proporcionar algo de tiempo para actualizar a la nueva versión de decoradores. Puede ser compatible con ambos por un tiempo, puede hacer un cambio duro y eliminar decoradores heredados en TypeScript 4+. No conozco la diferencia entre decoradores antiguos y nuevos, porque no los uso (bueno, característica experimental). Pero creo que los proyectos afectados deberían trabajar en la propuesta, si la propuesta no satisface sus necesidades. Es mejor para todos. TypeScript es el lugar equivocado para provocar la guerra sobre las características heredadas y experimentales.

Lamento haber aterrizado aquí: /

@RyanCavanaugh

Hay un conjunto muy limitado de cosas sintácticas que puede hacer con un complemento de Babel; Básicamente, el analizador ya tiene que admitirlo.

Verdadero. Pero con el interés de comparar con TypeScript, en Babel puede bifurcar solo el analizador y configurar su babel.config.js para usar el analizador personalizado y cualquier complemento de sintaxis personalizado que cree. Sí, es mucho trabajo (especialmente aprender a agregar nueva sintaxis por primera vez), pero no conozco ninguna opción equivalente para TS y, por supuesto, en Babel es mucho más fácil escribir complementos de transformación basados ​​en la sintaxis existente. No estoy seguro de cuál es el estado actual de las opciones de personalización en TypeScript, pero cuando lo examiné por última vez hace un par de años, parecía que no había otra opción para extenderlo más que bifurcarlo todo.

El hash para los privados, en mi opinión, es feo y confuso. Es de aplicación estricta porque no hay forma de implementarlos de otra manera. No hay ningún paso de compilación como en TS. El efecto es que simplemente obstruye el código con símbolos por el beneficio mínimo de un "privado estricto" y la gente piensa que es la forma "correcta" de escribir JS, ya que a muchas personas se les enseña que las cosas deben ser privadas por defecto.
Debería haber habido más propuestas antes de introducirlo en el estándar, especialmente cuando ha habido un desacuerdo obvio al respecto.

@ robot56 las cosas deberían ser privadas por defecto. Se les enseña que todas las cosas deben ser accesibles a través de la reflexión, lo que, de hecho, no es algo bueno para nadie.

@ljharb Sí, deberían hacerlo. Sin embargo, cuando la forma de declarar un privado se convierte en arrojar símbolos hash delante de las variables, la forma "correcta" de hacer una clase en JS significa enseñar a las personas a poner hash delante de las variables miembro. No solo al declararlos, sino también al hacer referencia a ellos. Es especialmente confuso si vienes de otros idiomas. Lo primero que pensé al ver algo como this.#x = this.#something(); y una declaración en una clase fue que el hash formaba parte de la propia variable. Nunca hubiera imaginado que era un modificador. El guión bajo para público, que también parece al revés. Esto no es realmente relevante para TS, pero supongo que solo una perorata molesta.

Sí, aprender cosas nuevas cuando uno está cimentado en la familiaridad puede ser un ajuste. ¡Tengo fe en que la comunidad JS seguirá aprendiendo!

(el hash es parte de la variable en sí, el nombre de this.#x no es "x, sino privado", pero de hecho, #x , un valor único en ese ámbito léxico)

Sí, aprender cosas nuevas cuando uno está cimentado en la familiaridad puede ser un ajuste. ¡Tengo fe en que la comunidad JS seguirá aprendiendo!

De la forma en que lo pones, suena como si eso fuera aprender algo que se suma a nuestra sabiduría de programación, mientras que esto es solo otra peculiaridad de JS que uno tiene que memorizar: D

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

Antony-Jones picture Antony-Jones  ·  3Comentarios

blendsdk picture blendsdk  ·  3Comentarios

remojansen picture remojansen  ·  3Comentarios

jbondc picture jbondc  ·  3Comentarios

fwanicka picture fwanicka  ·  3Comentarios