Typescript: Implémenter la proposition de champs privés

Créé le 26 juil. 2016  ·  134Commentaires  ·  Source: microsoft/TypeScript

Je pense qu'il serait bien que la proposition de champs privés de l'

Actuellement, la proposition n'inclut que des _propriétés_ privées, mais des méthodes devraient suivre. De plus, la partie la plus importante de la proposition est que les propriétés privées ne sont disponibles qu'au sein de la classe elle-même.

Committed Fixed Suggestion

Commentaire le plus utile

Je ne pense pas que les gens seront satisfaits d'une solution basée sur des mots clés non "privés".

Tous les 134 commentaires

Que pense l'équipe TypeScript de la syntaxe et de l'utilisation d'un préfixe de symbole/caractère ?

Personnellement , je pense que ça a l'air

Il serait triste de voir TypeScript perdre la syntaxe privée/protégée actuelle, qui est beaucoup plus propre et cohérente avec un certain nombre d'autres langages. Est-ce que cela risque d'arriver? Existe-t-il des alternatives ?

Pour ajouter à cela, il y a des discussions sur la possibilité de changer les symboles # et @ (c'est-à-dire en utilisant # pour les décorateurs), ce qui aurait évidemment un effet sur TypeScript aussi .

Je pense aussi que c'est "horrible". Je pense que, comme l'opérateur de liaison :: , qui n'a pas fait très loin, il vaut la peine d'essayer de l'implémenter jusqu'à ce qu'il soit un peu plus loin avec T39. Je soupçonne fortement que ce sera un peu difficile. De plus, le down-emit pour le prendre en charge sera assez difficile, je suppose, en raison de la nécessité de réécrire chaque site d'accès.

les usages doivent identifier la visibilité, pour des raisons que je ne comprends pas bien

Principalement parce que vous devez identifier sur le site d'utilisation comment rechercher la propriété, car il nécessite un algorithme de recherche différent afin que les classes descendantes puissent réutiliser les mêmes noms privés sans avoir besoin de "connaître" les propriétés privées des ancêtres.

Un avantage de la syntaxe proposée est que vous pouvez omettre le this et utiliser directement #field . De plus, le sceau peut être échangé avec des décorateurs (https://github.com/tc39/proposal-private-fields/issues/32) et à la place @ serait utilisé, donc vous utiliseriez @field , tout comme Ruby. Trouvez-vous cette syntaxe encore moche ?

Je ne pense pas que les gens seront satisfaits d'une solution basée sur des mots clés non "privés".

Je ne vois pas de bon moyen de le faire tout en prenant en charge eval comme le fait JavaScript - un jeton concret permet une certaine différenciation et permet de prendre en charge l'état privé qui n'est pas basé sur un système de type statique comme dans TypeScript . Nous avons discuté d'un certain nombre d'alternatives de syntaxe à https://github.com/tc39/proposal-private-fields/issues/14 , et je ne vois pas la syntaxe actuelle de TypeScript comme quelque chose qui peut fonctionner correctement tout le temps dans un environnement JS entièrement général.

Principalement parce que vous devez identifier sur le site d'utilisation comment rechercher la propriété, car il nécessite un algorithme de recherche différent afin que les classes descendantes puissent réutiliser les mêmes noms privés sans avoir besoin de "connaître" les propriétés privées des ancêtres.

J'aimerais en savoir plus sur le fonctionnement interne de JavaScript. Je pensais que cela fonctionnerait de la manière décrite ici et ici , mais apparemment non. J'ai toujours du mal à croire que cela aurait un impact significatif sur les performances, mais il n'y a pas de chiffres pour la comparaison.

Trouvez-vous cette syntaxe encore moche ?

Essentiellement, oui. Plus encore, je le trouve à la fois incompatible avec le reste de la syntaxe JavaScript, ainsi qu'avec de nombreux autres langages :

| Langue | Syntaxe | Remarques |
| --- | --- | --- |
| C# | int privé x; | |
| C++ | privé:
entier x; | |
| Java | int privé x; | |
| PHP | privé $x ; | |
| Python | __x | "pas de commentaire" |
| Rubis | privé
méthode def
# ...
fin | C'est une méthode, mais les champs sont privés
par défaut je pense. |
| TypeScript | privé x ; | |
| Visual Basic | Privé x en tant qu'entier | |

Tous les langages ci-dessus, sauf un, utilisent le mot-clé private , et il semble que Python n'ait pas vraiment d'état privé "correct".

À l'exception de Python (encore une fois), aucun des langages ne formate les déclarations de champs ou les accès aux champs différemment en fonction de la visibilité, et ils autorisent tous de nouveaux modificateurs de visibilité si cela est nécessaire.

Je pense aussi que # et @ fonctionnent mieux pour des choses comme les décorateurs, qui sont ( selon les mots de Kevin ) "syntaxiquement "en dehors" du flux impératif".

Je ne vois pas de bon moyen de le faire tout en prenant en charge l'évaluation générale comme le fait JavaScript

Serait-il possible d'expliquer ce problème en termes simples ? (peut-être dans https://github.com/tc39/proposal-private-fields/issues/14)

Ce serait bien d'avoir une liste de ces problèmes avec des exemples en un seul endroit, de sorte qu'il y ait quelque chose à quoi se référer.

J'ai toujours du mal à croire que cela aurait un impact significatif sur les performances, mais il n'y a pas de chiffres pour la comparaison.

Ce serait le cas, si vous voulez que ce soit vraiment privé plutôt qu'une simple convention comme c'est le cas dans TypeScript. Chaque fois que vous recherchez une propriété en JavaScript, le processus est essentiellement le suivant :

  1. Regardez par exemple pour votre propre propriété.
  2. S'il n'y a pas de propriété, regardez le prototype pour la propriété.
  3. Monter la chaîne de prototypes jusqu'à ce qu'aucune propriété n'ait été trouvée.
  4. Si trouvé, traitez le descripteur de propriété (inscriptible, get, set, configurable)
  5. S'il n'est pas trouvé et lu, retourne undefined ou écris, définit la valeur comme propre propriété si elle n'est pas scellée ou gelée.

Maintenant, avec des propriétés privées sans motif dans leur nom, vous n'auriez pas de propriétés propres, vous auriez quelque chose comme vos propres propriétés privées qui ne monteraient pas une chaîne de prototypes. Il faudrait alors les rechercher là aussi pour chaque opération qui pourrait éventuellement accéder aux propriétés privées, car vous ne pouvez pas être sûr de laquelle il s'agit. Le rechercher normalement et seulement s'il n'est pas trouvé en privé pourrait être très dangereux, car que se passe-t-il si vous trouvez quelque chose dans la chaîne de prototypes, mais qu'il existe également une version privée ?

Le plus gros défi est que les classes JavaScript sont encore un peu impropres. Ce sont essentiellement des sucres syntaxiques pour des fonctions de constructeur d'héritage prototypiques. Il y a une pensée qui m'est venue que je vais essayer d'ajouter à tc39/proposal-private-fields#14.

Serait-il possible d'expliquer ce problème en termes simples ?

Si cela nécessite de réécrire le site d'appel, vous ne pourrez jamais prendre en charge des éléments tels que :

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

Ou toute utilisation de eval comme des structures. Vous pouvez choisir de ne pas prendre en charge des éléments tels que l'accès à l'index pour les données privées ou l'absence de support d'évaluation, mais alors "pourquoi s'embêter". Presque tout cela a été souligné d'une manière ou d'une autre dans la proposition mais les gens sont toujours "mais j'aime le privé" 😁.

vous n'auriez pas vos propres propriétés, vous auriez quelque chose comme vos propres propriétés privées

Si vous aviez un seul ensemble de propriétés avec un élément visibility dans le descripteur, je suppose que le problème est que, si la propriété n'existait pas sur l'objet actuel, vous ne sauriez pas s'il faut ou non monter le chaîne de prototypes.

Si cela nécessite de réécrire le site d'appel, vous ne pourrez jamais prendre en charge des choses comme ...

AFAIK, cela ne sera pas pris en charge de toute façon ( réf ).

Je ne suis toujours pas vraiment le cas eval. Je pensais que les vérifications des propriétés se produiraient au moment de l'exécution, après le calcul des noms de propriété.

mais les gens sont toujours "mais j'aime le privé"

J'essaie de ne pas faire partie de ces personnes et de comprendre les problèmes, mais la syntaxe proposée me met mal à l'aise. =)

D'accord, je pense que je comprends le cas eval/rewrite maintenant. Les sites d'utilisation au sein de la classe seraient réécrits pour indiquer la visibilité en fonction des propriétés déclarées, et cela ne serait possible que s'il s'agissait de simples recherches.

Si vous aviez un seul ensemble de propriétés avec un élément de visibilité dans le descripteur, je suppose que le problème est que, si la propriété n'existait pas sur l'objet actuel, vous ne sauriez pas s'il faut ou non remonter la chaîne de prototypes.

Hmm. Mais s'il n'existe pas dans la classe actuelle, alors n'est-il pas par définition non privé ? Si tel est le cas, il devrait de toute façon remonter la chaîne de prototypes (comme avec les recherches de propriété publique régulières). Il n'y aurait pas de travail supplémentaire pour l'accès private .

(je rate peut-être quelque chose d'évident)

Mais s'il n'existe pas dans la classe actuelle, alors n'est-il pas par définition non privé ? Si tel est le cas, il devrait de toute façon remonter la chaîne de prototypes (comme avec les recherches de propriété publique régulières).

Non, vous ne voulez pas monter. Les labels privés ne sont pas hérités et les sous-classes peuvent réutiliser les privates sans se soucier des collisions de masquage/nom.

@ glen-84 Les deux messages que vous avez mentionnés indiquent des problèmes avec l'état privé non sigilé. Avez-vous des idées de solutions à ces problèmes ? Je pense que compliquer la chaîne de recherche serait risqué du point de vue de la compatibilité, rendrait JavaScript plus difficile à implémenter avec de bonnes performances (rendant peut-être les programmes existants plus lents), serait fondamentalement impossible à concilier avec les proxy et, en général, compliquerait considérablement le modèle mental du langage (qui possède déjà un système d'objets relativement complexe).

Dans la comparaison multilingue, vous mentionnez Ruby. Je pense que Ruby est un bon exemple d'état privé _avec_ un sceau-- @ . Vous pouvez appeler des méthodes getter et setter sans sceau.

Non, vous ne voulez pas monter. Les labels privés ne sont pas hérités et les sous-classes peuvent réutiliser les privates sans se soucier des collisions de masquage/nom.

Je voulais dire monter si la propriété n'était pas dans la classe actuelle, pour rechercher une propriété publique ou protégée.

Les deux messages que vous avez mentionnés indiquent des problèmes avec l'état privé non sigilé. Avez-vous des idées de solutions à ces problèmes ?

C'est très difficile pour moi de le faire, en tant que personne ne comprenant pas le fonctionnement interne de JavaScript.

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

Je n'ai aucune idée de ce que cela signifie. Pourquoi est-ce? C'est impossible à faire ?

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.

Tellement optimisé qu'un simple interrupteur de visibilité affecterait considérablement les performances ?

Would for-in enumerate over these properties?

Je suppose que cela dépend du contexte. Dans la même classe, oui. Cependant, ce n'est pas une raison pour ne pas utiliser private , c'est un détail d'implémentation, et d'autres langages ont probablement déjà répondu à ces questions.

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

Probablement oui (la visibilité est augmentée) à la première question, et non à la seconde. Encore une fois, tout cela a déjà été fait, n'est-ce pas ?

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 visibilité n'est qu'un outil d'encapsulation et de définition d'une interface publique. 99% des développeurs ne se soucient probablement pas des "fuites d'informations". Cela dit, j'ai suggéré deux fonctionnalités distinctes ici . Peut-être que cette proposition pourrait être appelée autrement, comme « état caché » ou « état sécurisé », et permettre à quelque chose comme l'état privé/protégé d'être mis en œuvre différemment.

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

Utilisez "état caché/sécurisé" si vous voulez des performances. :D Plus sérieusement, de quel type de perte de performances parlons-nous ? Peut-être que quelqu'un peut créer un prototype. =)

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

L'auto-hébergement intégré (si je comprends même ce que cela signifie) ne serait-il pas vraiment mauvais pour les performances ? Sinon... utilisez "état caché/sécurisé" et non une visibilité privée/protégée de niveau supérieur.

Je pense que compliquer la chaîne de recherche serait risqué du point de vue de la compatibilité

Je ne suis pas la première/la seule personne à penser que c'est ainsi que cela pourrait/peut fonctionner. Vous accédez à une propriété, elle recherche un descripteur pour la visibilité et répond en conséquence. Cela ne semble pas compliqué si vous n'avez aucune idée de comment les choses fonctionnent vraiment dans JS. J'ai vraiment besoin de lire un cours accéléré sur les algorithmes de recherche de propriétés/internes JS. =P

Je pense que Ruby est un bon exemple d'état privé avec un sigil--@

Ruby n'est même pas un langage de la famille C, et il semble qu'il n'y ait pas de champs publics, mais seulement des getters et des setters (accesseurs). La proposition actuelle d'état privé a plusieurs déclarations côte à côte, avec le même objectif général (déclarer des propriétés), mais des syntaxes visiblement différentes et incohérentes.

Cela dit, je suis complètement dépassé ici et j'ajoute très probablement plus de bruit que de valeur, alors je vais essayer de me taire et de laisser les experts parvenir à un consensus.

Je discuterai de ce souhait avec TC39 et nous verrons si nous pouvons trouver d'autres idées sur la façon d'éviter un préfixe. Je n'en ai pas, personnellement. Notez que, si TypeScript décide d'implémenter des champs privés, ils sont toujours à l'étape 1 dans TC39 et donc sujets à changement.

Que pense l'équipe TypeScript de la syntaxe et de l'utilisation d'un préfixe de symbole/caractère ?

Personnellement, je trouve que ça a l'air horrible...

Remarque J'ai fait une suggestion pour se débarrasser de l'affreuse syntaxe # .

@shelby3 Malheureusement, je ne vois pas cela comme une option réaliste. tl;dr, nous devons nous soucier de la façon dont tout va interagir avec eval ; ne pas inclure de sceau rend tout simplement "trop ​​dynamique" pour fonctionner correctement.

@littledan J'ai suivi là-bas maintenant et j'ai fait maximiser la compatibilité avec TypeScript . Je comprends maintenant pourquoi nous devons déclarer la confidentialité des arguments de méthodes non typés.

@isiahmeadows

Cela remplacera principalement l'implémentation pseudo-privée actuelle [...] De plus, la partie la plus importante de la proposition est que les propriétés privées ne sont disponibles que dans la classe elle-même.

J'espère que cela ne remplacera pas l'implémentation pseudo-privée. Je pense que la disponibilité uniquement au sein d'une classe n'est en fait pas une si bonne chose (étant donné que par disponibilité, vous entendez accessibilité ). J'admets qu'il peut y avoir des situations particulières où il est logique d'avoir des propriétés strictement privées et inaccessibles, par exemple pour des raisons de sécurité. J'admets également que cela est évidemment déroutant pour les personnes familières avec d'autres langages, que private n'est en fait pas si privé en JavaScript. Mais à part des raisons de sécurité, à mon avis, la plupart des développeurs devraient utiliser private plupart du temps uniquement pour définir un contrat mais pas pour contrôler l'accessibilité.

Par exemple, du point de vue des architectes, je pense qu'une très bonne chose à propos du mot-clé TS private et sa nature pseudo-privée est

  • qu'il permet d'exprimer le contrat d'interface d'un type et comment il est destiné à être utilisé par les clients
  • que le contrat est vérifié au moment de la compilation par le compilateur TS
  • que je peux toujours "violer" consciemment le contrat au moment de l'exécution, en particulier pour les tests unitaires en boîte blanche.

L'accessibilité des propriétés privées au moment de l'exécution contribue beaucoup à la testabilité car je suis capable d'injecter un état privé dans une classe en cours de test en définissant simplement ses champs privés (dans TypeScript, je recommande d'utiliser la notation entre crochets au lieu de convertir any raison d'une meilleure prise en charge de la refactorisation), par exemple :

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

Pas besoin de code de test compliqué juste pour configurer une classe avec un état (privé) particulier.
Un autre avantage des propriétés pseudo-privées est qu'elles sont essentielles au patching de singe .

Je ne pense pas que la communauté TypeScript changerait volontiers toutes leurs lignes private variable en private #variable .

Du point de vue de TypeScript, la plupart d'entre nous sont satisfaits de nos belles et douces illusions d'un bon langage (intellisense, erreurs de construction, types, divers sucres). Ces illusions nous donnent une meilleure expérience de développement, nous écrivons un meilleur code plus rapidement. C'est la principale raison pour laquelle nous utilisons TS en plus de la transpilation ESNext - mais pour cette dernière, il y a Babel et c'est mieux (ou du moins c'était mieux lors de ma dernière vérification).

Je ne parle pas de ces quelques personnes qui veulent en fait quelque chose de plus des variables privées qu'un sucre syntaxique dans leurs fichiers source. Je pense que ces gars ont besoin de quelque chose de plus fort, peut-être plus proche du code natif.

Mais pour le reste nous : nous n'avons pas vraiment besoin de JS private. Nous avons besoin des variables private convenient simples et faciles comme nous les avons utilisées en C++, Java, C#, etc.

Veuillez voter pour une solution qui ne sera pas une douleur pour nous. Peut-être soft privé? Parce que je doute que nous voulions que le sceau soit privé #variable . Ou peut-être que TS private et ES private seraient des concepts différents ? Moche.

@igabesz

Je ne pense pas que la communauté TypeScript changerait volontiers toutes leurs lignes private variable en private #variable

En fait, avec cette proposition, private serait inutile. Au lieu de cela, le sigil # remplace entièrement sans conflit.

Mais pour le reste nous : nous n'avons pas vraiment besoin de JS private. Nous avons besoin de variables pratiques privées simples et faciles comme nous les avons utilisées en C++, Java, C#, etc.

Le private de TypeScript est soft private, comme celui de la plupart des langages OO. Même les variables privées de Java sont toujours techniquement privées, car elles sont toujours accessibles avec une trappe d'évacuation. JS private équivaut à utiliser une fermeture, sauf que vous pouvez toujours accéder à l'état privé des instances non this .

Veuillez voter pour une solution qui ne sera pas une douleur pour nous. Peut-être soft privé? Parce que je doute que nous voulions le sceau privé #variable. Ou peut-être que TS private et ES private seraient des concepts différents ? Moche.

Ce seraient des concepts différents, mais en général, les trappes de secours sont rarement utiles dans la pratique. La principale exception concerne l'inspection d'objets (par exemple, les outils de développement, Node.js util.inspect ), mais la plupart sont définis par l'hôte et utilisent déjà des API natives privilégiées maintenant, il n'est donc pas nécessaire de l'ajouter à la spécification.

De plus, une fois que ES aura standardisé l'état privé, TS l'adoptera et dépréciera probablement son propre mécanisme de soft-private, qui sera supprimé dans la prochaine version majeure. Il a toujours été un sur-ensemble strict d'ES, et il a ajouté (fonctions asynchrones), modifié (classes) et/ou déconseillé ( /// <amd-dependency /> ) des fonctionnalités nécessaires au fur et à mesure de l'évolution d'ES, pour se maintenir comme un strict superset et ne pas dupliquer la spécification actuelle.

De plus, une fois que ES aura standardisé l'état privé, TS l'adoptera et dépréciera probablement son propre mécanisme de soft-private, qui sera supprimé dans la prochaine version majeure.

??

De plus, une fois que ES aura standardisé l'état privé, TS l'adoptera et dépréciera probablement son propre mécanisme de soft-private, qui sera supprimé dans la prochaine version majeure.

Ce n'est pas la position de l'équipe TS. nous n'avons pas l'intention d'abandonner quoi que ce soit de sitôt.
Si et quand la proposition d'état privé atteint l'état correct, TS la mettra en œuvre. Je ne pense pas que cela ait d'implication sur les privés car TS les implémente aujourd'hui.

@mhegazy D'accord. Je me suis trompé. (C'était une supposition éclairée, BTW.)

La proposition de champs de classe est maintenant à l' étape 2, donc je suis heureux que l'équipe TypeScript y réfléchisse et soit prête à suivre les normes EcmaScript 💯

Si et quand la proposition d'état privé atteint l'état correct, TS la mettra en œuvre.

@mhegazy L'étape 3 est-elle le bon moment pour mettre en œuvre ?

EDIT : j'ai peut-être trouvé ma réponse

@styfle voir la discussion des notes de réunion de conception (#16415) qui traite des considérations actuelles concernant la mise en œuvre.

L'étape 3 est-elle le bon moment pour la mise en œuvre ?

Oui. Nous commençons à étudier les différentes conceptions possibles pour cette fonctionnalité.

La proposition des champs de classe est maintenant à l'étape 3. (il y a un mois)

Alors que les champs de classe ont atteint l'étape 3, les méthodes privées et les accesseurs ont suivi, et étaient à l'étape 2 jusqu'à hier, date à laquelle ils ont été déplacés à l'étape 3. Désormais, tout ce qui est nécessaire pour s'adresser aux membres privés des classes est à l'étape 3.

Une mise à jour sur la position/progrès de l'équipe TS sur l'adoption de la syntaxe #[field] maintenant qu'elle est à l'étape 3 depuis un certain temps ? Personnellement, je ne l'aime vraiment pas et je préfère de loin le mot-clé private existant de TS, mais en même temps, je veux être aussi proche que possible des normes.

Personnellement, je ne l'aime vraiment pas et je préfère de loin le mot-clé privé existant de TS

moi aussi c'est trop moche

mais @mhegazy j'aimerais (essayer) de faire ça, pourrais-je ?

L'analyse ne devrait pas être mauvaise (presque un nouveau modificateur qui n'est qu'un jeton, presque), mais la vérification de type sera pénible (puisque nous aurons deux types différents de privés qui devront être comparés d'une manière ou d'une autre), et le l'émission de niveau inférieur est atroce (parce que réduire la confidentialité du temps d'exécution réel est une grande transformation - @rbuckton a des idées là-dessus, et peut-être une implémentation (je n'en suis pas sûr, il en a beaucoup dans sa fourchette)). Techniquement, nous ne pouvons pas vous empêcher d'essayer, mais je ne le recommanderais pas, si vous trouvez quelque chose d'autre que vous préférez essayer, et je ne peux pas garantir que nous serions prêts à l'accepter une fois que vous aurez terminé. De plus, bien que les champs et méthodes privés aient progressé, ils sont encore légèrement incomplets jusqu'à ce que les statiques privées (et éventuellement les décorateurs ) progressent également (étant donné la façon dont ils interagissent tous, il peut être préférable de les ajouter tous en même temps).

Autant dire qu'il y en a beaucoup ici.

@weswigham Ok, j'abandonne

Voici un avertissement que je (avec

Mise à jour : Notre travail en cours est ici .

Oui. Nous commençons à étudier les différentes conceptions possibles pour cette fonctionnalité.

Je n'aime pas non plus la syntaxe # , mais je comprends les raisons techniques derrière cette syntaxe. @mhegazy Ce que j'aimerais vraiment faire par une équipe TypeScript après avoir mis en œuvre une nouvelle proposition pour réfléchir à ce que TypeScript va faire avec des implémentations obsolètes comme namespace , private qui peuvent être utilisées mais devraient généralement pas car il existe une meilleure façon es-standard de faire la même chose ou presque.

Je voudrais aussi ajouter mes quelques centimes à propos de protected . Si (maintenant, espérons-le) nous allons supprimer/déprécier le mot-clé private un jour, je pense que c'est bien de faire la même chose avec le mot-clé protected . Je sais que la plupart des gens peuvent ne pas être d'accord, mais oui, des étendues de visibilité supplémentaires peuvent parfois être utiles, mais la valeur globale de celle-ci n'est pas élevée à mon humble avis.

@pleerock ,

Voici ce que je m'attendrais à voir de TypeScript :

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

Émettre (en ciblant ESNext) :

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

Emit (ciblant ESNext, avec une nouvelle option de compilateur pour émettre des champs marqués comme privés en tant que champs privés ES) :

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

Cela devrait être rétrocompatible, tout en vous permettant également d'utiliser des champs privés ES avec une syntaxe propre.

@glen-84 bien sûr, je parlais d'un plan à long terme sur les mots-clés et les syntaxes obsolètes

Nous n'avons pas l'intention de déprécier une syntaxe ou des mots-clés.

Je ne pense pas non plus que nous aurons une quelconque option pour transpiler private en # - ils ont un comportement attendu différent ; # est la confidentialité de l'exécution dure, tandis que private n'est que la confidentialité de la conception.

@weswigham, je le pense aussi. @RyanCavanaugh ouais, c'était la réponse attendue. Mais j'appliquerais toujours au moins une stratégie pour un nouvel utilisateur afin d'éviter d'utiliser des mots-clés d'espace de noms/privés car à mon humble avis, ils sont devenus obsolètes avec les dernières propositions ecmascript

Les gens comprennent généralement cela en lisant la documentation, que nous mettons bien sûr à jour. module foo { est toujours dans le langage mais n'est pratiquement plus jamais vu à l'état sauvage, sauf dans de très anciennes bases de code antérieures à namespace foo { .

@RyanCavanaugh, c'est bien d'entendre ça. Mais je crois toujours que les nouvelles personnes venant de c#, disons, essaieront certainement d'utiliser des espaces de noms (pas tous, mais certains d'entre eux). Je suppose que la même chose pourrait être avec les utilisateurs venant d'autres langues - ils commenceront à utiliser private au lieu de # et cela a tendance à être plus massif que l'exemple avec les espaces de noms

Je ne pense pas non plus que nous aurons une quelconque option pour transpiler private en # - ils ont un comportement attendu différent; # correspond à la confidentialité de l'exécution stricte, tandis que privé correspond uniquement à la confidentialité au moment de la conception.

Oh. J'espérais que nous pourrions également utiliser private pour une confidentialité stricte, afin d'éviter la ... syntaxe malheureuse.

Quoi qu'il en soit, soft-private est probablement suffisant pour mes cas d'utilisation (actuels).

Je pense que ce serait formidable d'inclure cette prise en charge de la syntaxe dans la prochaine version 3 de TypeScript, car cette fonctionnalité est énorme et la version 3 semble être une bonne occasion pour inciter les gens à commencer à utiliser la nouvelle syntaxe # .

EDIT : sacrément oublié que la version 3 est déjà sortie.

Juste pour info, il y a eu un récent afflux de champs/slots privés/quoi que ce soit dans le dépôt de la proposition TC39, il n'est donc même pas certain que la proposition dans sa forme actuelle le fera. Voici quelques problèmes pertinents :

Je ne suis pas TC39, mais ma suggestion personnelle à tout le monde est d'abord d'attendre que la syntaxe se solidifie à nouveau (éventuellement d'attendre l'étape 4), puis de la mettre en œuvre.

FWIW Je n'interpréterais pas la discussion dans tc39/proposal-class-fields#100 pour indiquer quoi que ce soit en particulier. # n'est pas joli à première vue, mais aucune forme syntaxique préférable n'a été suggérée et la seule syntaxe que les gens semblent vouloir n'est manifestement pas réalisable. Il doit y avoir une sorte de sceau de préfixe et toutes les tentatives pour permettre à this.someProp d'être privé sont vouées à l'échec.

Je me rends compte que cela semble plutôt dédaigneux, mais franchement, c'est mon intention - aucun des plaignants dans ces fils de discussion ne s'est engagé de manière significative avec les problèmes techniques de base traités dans les fils de discussion existants ou la FAQ. C'est déprimant comme diable de lire les fils de discussion sur ce dépôt et de voir de longues explications correctes sur les raisons pour lesquelles un sceau est nécessaire.

Si la fin du jeu est que personne n'utilise de champs privés à moins qu'il n'ait vraiment besoin d'une confidentialité d'exécution stricte, c'est probablement un bon résultat pour le Web en termes de performances et de débogage.

Je suis d'accord que ce n'est probablement pas un problème idéal à mentionner, mais l'autre,
tc39/proposal-class-fields#106, est probablement beaucoup plus indicatif - il y a
discussion sérieuse sur l'utilisation de cartes faibles à la place, entre autres, parce que
L'interopérabilité du proxy est vraiment nulle.


Isiah Meadows
[email protected]
www.isiahmeadows.com

Le lundi 30 juillet 2018 à 15h38, Ryan Cavanaugh [email protected]
a écrit:

FWIW Je n'interpréterais pas la discussion en
tc39/proposition-classe-champs#100
https://github.com/tc39/proposal-class-fields/issues/100 être
indicatif de quelque chose en particulier. # n'est pas joli à première vue, mais
aucune forme syntaxique préférable n'a été suggérée et la seule syntaxe qui
les gens semblent vouloir n'est manifestement pas réalisable. Il doit y avoir un préfixe
sceau d'une certaine sorte et toutes les tentatives pour permettre à this.someProp d'être privé
sont voués à l'échec.

Je me rends compte que cela semble plutôt dédaigneux, mais franchement, c'est mon intention -
aucun des plaignants dans ces fils ne s'est engagé de manière significative avec le
problèmes techniques de base traités dans les fils de discussion existants ou dans la FAQ. C'est
déprimant comme diable de lire les discussions sur ce référentiel et de voir longtemps
des explications
sol.

Si l'objectif ultime est que personne n'utilise des champs privés à moins qu'ils ne vraiment
besoin d'une confidentialité d'exécution dure, c'est probablement un bon résultat pour le Web dans
termes de performances et de débogage.

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/Microsoft/TypeScript/issues/9950#issuecomment-408984395 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AERrBGCphyQUu5lJQW7lgsqALLL3e0_Wks5uL2DLgaJpZM4JVDwV
.

Il y a des discussions sur l'utilisation de WeakMaps, mais je ne vois pas en quoi cela améliorerait l'interaction avec Proxy. J'inviterais tout membre du TC39 qui a une autre idée sur la façon dont les fonctionnalités de classe privée devraient fonctionner à la présenter au comité pour commentaires ; actuellement, cette proposition est à l'étape 3 et représente théoriquement la position consensuelle du comité. De nombreuses personnes ont fait des compromis pour atteindre un objectif commun d'activation de cette fonctionnalité, même si d'autres conceptions sont possibles.

Je travaille à organiser une discussion parmi les frameworks sur la façon d'utiliser Proxy pour observer les mutations d'objets, et comment cela devrait interagir avec les champs privés. Faites-moi savoir si vous souhaitez vous joindre à la conversation.

@RyanCavanaugh

FWIW Je n'interpréterais pas la discussion dans tc39/proposal-class-fields#100 pour indiquer quoi que ce soit en particulier. # n'est pas joli à première vue, mais aucune forme syntaxique préférable n'a été suggérée et la seule syntaxe que les gens semblent vouloir n'est manifestement pas réalisable. Il doit y avoir une sorte de sceau de préfixe et toutes les tentatives pour permettre à this.someProp d'être privé sont vouées à l'échec.

En retard, mais il y a en fait une proposition suggérant la syntaxe this->var .

Certes, cette proposition est très probablement morte ("le comité n'était pas enthousiasmé" est la seule raison que j'ai pu trouver). Mais une syntaxe alternative a en effet été proposée, et j'espère que toutes les parties intéressées les connaissent et les connaissent.

Je pense qu'il serait bien d'avoir une option de compilateur pour faire transpiler private vers une sorte de _soft_ private qui serait appliqué au moment de l'exécution. Je ne pense pas que le cas d'utilisation pour avoir besoin de true hard private soit particulièrement courant, donc même en dehors de toute aversion pour la syntaxe # , je pense que la plupart des gens auraient tendance à s'en tenir à private . Mais au moment de la compilation, seul le privé est _too_ soft IMO. En outre, une telle option aiderait à réduire le nombre de variantes possibles de private... si les développeurs sont laissés à eux-mêmes pour l'implémenter, vous pourriez avoir tout cela :

class Demo {
  private a

  #b

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

Je propose donc qu'avec la nouvelle option activée, private a se transpile en <strong i="13">@reflect</strong> #a , où @reflect est un décorateur qui permet la réflexion sur la propriété via une API prise en charge par la communauté. Il a été question d'une bibliothèque de décorateurs standard, donc le décorateur @reflect (ou quel que soit le nom que nous voudrions lui donner) pourrait être standardisé à l'avenir ; Je pense que ce serait un bon candidat pour ça.

Je suppose que le principal inconvénient de ma proposition serait l'impact sur les performances. Nous pouvons espérer qu'un jour JS aura des décorateurs standard implémentés nativement pour les optimiser, mais la réalité dans un avenir prévisible est que <strong i="19">@reflect</strong> #x serait plus lent que juste #x . Mais je ne propose cela que comme une option, qui devrait probablement être désactivée par défaut (pour des raisons de compatibilité descendante également).

@MichaelTheriot

Plus tard, mais il y a en fait une proposition suggérant cette syntaxe->var.

Certes, cette proposition est très probablement morte ("le comité n'était pas enthousiasmé" est la seule raison que j'ai pu trouver)

Le comité a donné de nombreuses raisons mûrement réfléchies pour approuver la proposition actuelle au lieu de la proposition des classes 1.1, par exemple https://github.com/tc39/proposal-class-fields/issues/100#issuecomment -429460917

@mbrowne

Je l'ai peut-être manqué. La page des problèmes des classes 1.1 est inactive depuis six mois, et même l'exemple que vous avez lié a été écrit un mois après mon commentaire.

Pour info, je l'ai mentionné dans le fil que vous avez lié il y a plusieurs mois. Mon commentaire ici était juste pour répondre à une idée fausse selon laquelle aucune syntaxe alternative n'a été proposée, car je pense que toutes les parties impliquées doivent être conscientes que ce n'est pas le cas.

Edit : Mon commentaire ne suggère pas que TypeScript fasse quelque chose de différent. Je pense qu'il est utile de corriger la désinformation sur les questions référencées d'une proposition.

@MichaelTheriot, les parties qui doivent être informées des propositions d'alternatives ne sont pas les parties impliquées dans cette conversation. TypeScript suivra la proposition qui est en passe d'être ratifiée. Le fait que des syntaxes alternatives aient été proposées et non adoptées n'est pas vraiment utile pour cette conversation à mon avis.

Hé les gars, au cas où cela aiderait, j'aimerais partager ma propre implémentation de membres protégés/privés d'exécution :

Voir lowclass .

Consultez les fichiers de test complets montrant toutes sortes d'utilisations des membres d'exécution publics/protégés/privés. L'implémentation n'est pas longue, et certaines fonctionnalités peuvent être omises afin de n'avoir que la fonctionnalité minimale protégée/privée.

Remarques:

  • Il utilise WeakMaps pour stocker l'état protégé/privé.
  • Contrairement à d'autres implémentations que j'ai vues, cela fonctionne avec du code asynchrone avec des rappels/promesses/attentes car il ne repose pas sur le traçage de pile d'appels synchrone.
  • Il fonctionne avec les getters/setters (y compris les super calls) (voir tests).
  • Fonctionne avec super natif, ou en utilisant un Super helper pour ES5 (voir tests).
  • Prend en charge la méthode constructor (voir tests).
  • Possibilité d'étendre les classes intégrées (à l'exception de Date, mais je voulais étudier cela bien que les gens disent que ce n'est pas possible mais je veux le confirmer. Voir les tests, par exemple travailler avec des éléments personnalisés natifs).
  • Possibilité d'étendre les class natifs réguliers (voir tests).
  • wrap natif class es, leur donnant des capacités protégées et privées (voir tests).
  • Écrivez des classes de function style ES5 au lieu d'es class natifs (voir tests).
  • beaucoup de place pour l'optimisation des performances (par exemple, la mise en cache des appels d'aide super/protégés/privés et l'optimisation des algorithmes de recherche)

Pour exécuter des tests :

npm install
npm test

Voir également https://github.com/babel/proposals/issues/12 et https://github.com/babel/babel/issues/8421 pour plus de détails et les problèmes liés à la mise en œuvre de Babel.

Bonjour à tous,

veuillez ne pas implémenter la spécification des champs de classe privée non encore finalisés. Il a des problèmes.

Veuillez lire ce fil .

J'encourage tous ceux qui liront ceci à jeter un œil à d' autres idées de syntaxe (il suffit de parcourir, il y a plus) et d'exprimer vos opinions.

fe voici un autre fil (avec de meilleures idées de syntaxe que le # IMHO actuel).


S'il existe une communauté JavaScript utilisant déjà largement public/privé/protégé, c'est la communauté TypeScript qui a de grandes chances de contribuer à façonner l'avenir de JS privé/protégé.

Ainsi, les champs de classe privés sont fournis dans V8 v7.2 et Chrome 72. Est-il prévu de commencer à mettre en œuvre la proposition de champs privés ?

@ChrisBrownie55 Les champs publics sont

@jhpratt c'est mon mauvais, mais il semblerait que l'équipe Chrome envisage de livrer en privé dans un proche avenir

Pour référence : https://v8.dev/blog/v8-release-72#public -class-fields

Il documente qu'ils expédient des champs de classe publique à partir de V8 7.2, mais il y a ceci concernant les champs privés (c'est moi qui souligne):

La prise en charge des champs de classe privée est prévue pour une future version V8 .

@isiahmeadows Je

Screenshot of Google Developers page

Conclusion

Les champs de classe publique sont expédiés dans V8 v7.2 et Chrome 72. Nous prévoyons d' expédier les champs de classe privée bientôt.

Lien vers l'article sur le blog des développeurs de Google

Ces articles ont été écrits par @mathiasbynens et Andreas Haas, à qui vous pouvez demander des éclaircissements si nécessaire (bien que je pense que chacun de ces messages était assez clair). cc @gsathya et @joyeecheung qui travaillent sur les finitions de l'implémentation en V8.

Quoi qu'il en soit, la réunion du TC39 de janvier 2019 a clôturé un an et demi de repenser les alternatives aux propositions de champs et de méthodes privés avec une nouvelle réaffirmation du consensus sur les propositions. Je pense que nous pouvons considérer la version actuelle comme stable et prête à l'emploi pour TypeScript.

Chrome vient de publier des champs de classe privés 🎉
Ils ne sont disponibles que dans Chrome 74 actuellement publié dans la version _canary_.

screenshot of tweet

Je viens d'envoyer des champs de cours privés dans Chrome 74 ! Essayez-le dans Chrome Canary dès aujourd'hui !
— Sathya Gunasekaran via Twtiter

Est-ce que quelqu'un sait où nous en sommes ici pour choisir une implémentation spécifique (ou en créer une) pour les champs de classe privés ? J'ai vu que @trusktr recommandait lowclass mais je ne sais pas si "_Private Inheritance_" fait partie de la spécification.

Ce n'est décidément pas le cas ; les champs privés ne parcourent pas la chaîne de prototypes (car alors d'autres objets pourraient les voir, et donc ils ne seraient pas privés)

Je suppose que les champs privés seront transpilés en WeakMaps (un WeakMap par champ, de la même manière que Babel le fait). Il devrait également y avoir une option pour conserver la syntaxe # dans la sortie finale, pour ceux qui ciblent exclusivement les navigateurs qui la prennent en charge (cela deviendra bien sûr plus pertinent avec le temps).

Pour des raisons de performances, il pourrait également être intéressant d'envisager une option qui permettrait aux développeurs d'utiliser la syntaxe # pour une compatibilité future (lorsque plus de navigateurs la prendront en charge), mais en fait transpiler vers des propriétés publiques avec un préfixe spécial, par exemple __ts# . WeakMaps doit être comparé pour voir si cela est réellement nécessaire, mais je soupçonne que la différence de performance entre les propriétés publiques et WeakMaps pourrait être importante. Si une telle option était ajoutée, elle devrait être désactivée par défaut bien sûr, car les développeurs utilisant la syntaxe # s'attendraient normalement à ce qu'elle soit à la fois privée à la compilation et à l'exécution. Mais pour ceux qui souhaitent maximiser les performances d'exécution et se contentent de la compilation privée en attendant, cela pourrait être un bon moyen de commencer à utiliser la nouvelle syntaxe sans potentiellement entraîner de dégradation des performances.

Des mises à jour sur l'avancement de la mise en œuvre ? Peut-être un PR que nous pouvons construire pour tester et fournir des commentaires ?

@jhpratt bien sûr ! Si vous consultez la branche dans ce PR , vous pourrez tester les champs d'instance à nom privé. Les méthodes et les accesseurs sont en cours.

Nous espérons remonter ce travail en amont. Nous pouvons PR les modifications par rapport à ce référentiel (Microsoft/TypeScript) dès que ce PR préalable est fusionné : https://github.com/Microsoft/TypeScript/pull/30467.

Les commentaires sont les bienvenus.

Je ne sais pas si "Héritage privé" fait partie de la spécification.

Sidenote, je prévois de supprimer cette fonctionnalité en classe basse, pour permettre une véritable confidentialité à 100%. Je n'en ai pas vraiment eu besoin en pratique, c'était plus une expérience.

Au fait, j'ai envie de poster ici, au cas où une théorie sur "l'héritage privé" pourrait éventuellement être utile (peut-être juste intéressante, ou peut-être aider à susciter d'autres idées):


au cas où ça t'intéresse :

"Héritage privé" (comme on le voit dans la version actuelle de lowclass) signifie qu'une sous-classe peut utiliser des méthodes privées héritées d'une superclasse, mais la méthode applique les modifications _ uniquement _ aux propriétés privées de l'instance _dans la portée de cette sous-classe_, comme si la sous-classe avait ces méthodes définies comme méthodes privées dans sa propre définition, mais la sous-classe ne peut pas modifier les propriétés privées de l'instance dans une portée de super-classe ou de classe sœur.

En comparaison, dans "l'héritage protégé", une sous-classe _peut_ modifier les propriétés de sa propre instance ou instance de superclasse, mais ne peut toujours pas modifier les propriétés d'une classe sœur. Dans l'héritage protégé, une sous-classe modifie les propriétés que toutes les super classes sont capables de voir (les super classes sont toutes en lecture/écriture dans ces mêmes propriétés).

En d'autres termes, dans le concept "d'héritage privé", chaque classe a une portée privée et toutes les méthodes privées héritées ne fonctionnent que sur la portée de classe locale, contrairement à protected où les méthodes protégées fonctionnent sur une seule portée pour toute la hiérarchie de classes.

Je ne sais pas si cela avait beaucoup de sens, voici donc des exemples de code simples pour expliquer à quoi « l'héritage privé » serait similaire, si nous l'écrivions en utilisant les fonctionnalités de champ privé actuelles de ecma proposition-class-fields :


l'exemple de code est plus facile à comprendre :

Il n'y a pas d'"héritage privé" dans les champs de classe de proposition, donc ce qui suit ne fonctionnera pas (et je suis d'accord que c'est souhaitable, pour maintenir une véritable confidentialité):

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 lowclass, « l'héritage privé » équivaudrait à écrire le code non DRY suivant pour émuler la même chose, en utilisant un copier/coller dans votre éditeur :

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)
    }
}

Dans les deux exemples, la variable #foo est une variable spécifique à chaque classe. Il y a deux variables #foo , pas une ; chacun lisible et inscriptible uniquement par code dans la même définition de classe.

En lowclass, l'héritage privé nous permet de réutiliser des méthodes de superclasse privées, _mais_ la méthode opère dans la portée où la méthode est utilisée. C'est donc comme si nous copiions et collions la méthode de la superclasse dans la sous-classe, comme dans l'exemple ci-dessus, mais il y a toujours deux variables #foo distinctes pour chaque classe.

En lowclass, si #someMethod est utilisé dans la superclasse, il opère sur les #foo de la superclasse. Si #someMethod est utilisé dans la portée de la sous-classe, il opère sur les #foo de la sous-classe, pas sur les #foo de la superclasse !

J'espère que cela explique le concept, et même s'il ne sera pas utilisé, j'espère que cela pourra être intéressant ou utile pour susciter des idées de toutes sortes.

C'est maintenant dans le canal stable de Chrome, donc les développeurs peuvent l'utiliser nativement. Je suis principalement intéressé par ce problème à cause de VSCode - lors de l'écriture du javascript vanille .js , VSCode le marque comme une erreur. Existe-t-il un moyen d'ajouter la prise en charge des champs de classe privés dans Vanilla JS dans VSCode indépendamment du débat sur l'opportunité de les ajouter à Typescript?

Personnellement, je ne pense pas que TS devrait ajouter une prise en charge pour eux avant d'atteindre l'étape 4. TS a déjà un privé à la compilation qui fonctionne assez bien pour le moment. Après avoir atteint le stade 4, je suis d'accord que cela a du sens. (Il y a également eu des épisodes de flux occasionnels dans la discussion, donc je ne la considérerais toujours pas comme prête pour les heures de grande écoute.)

Mise à jour : il est également pris en charge dans Node 12 stable. De plus, Babel a un plugin pour transformer cette syntaxe. Les développeurs utilisent souvent des fonctionnalités avant qu'elles ne deviennent des propositions de l'étape 4. J'aimerais voir une prise en charge ajoutée pour cette syntaxe dans Vanilla JS (non-ts) ou un moyen de l'activer via jsconfig.json afin que VSCode n'affiche pas d'erreur lors de leur utilisation. Le référentiel VSCode indique que leur support JS est soutenu par TypeScript et fait référence à ce problème.

Je dois dire qu'il n'est pas logique que TypeScript ne prenne pas du tout en charge la fonctionnalité puisqu'elle existe déjà en production dans un navigateur majeur et Node. Cela ne veut pas dire que TypeScript doit tout solidifier complètement maintenant et le publier en tant que fonctionnalité par défaut.

Je suggérerais que TypeScript introduise des champs privés sous un indicateur qui indique que cette fonctionnalité est expérimentale et est susceptible de changer entre l'étape 3 et l'étape 4.

Peut-être pourrions-nous d'abord implémenter le support de la syntaxe sans sémantique ?

Peut-être pourrions-nous d'abord implémenter le support de la syntaxe sans sémantique ?

Pour la vérification de type/intellisense, je pense qu'il doit y avoir une sorte de sémantique, mais ne peut avoir aucun support de transformation de bas niveau comme BigInt (ne peut être utilisé qu'avec esnext ).

fwiw, il n'est susceptible d'être modifié qu'à l'étape 3 en raison des commentaires sur la mise en œuvre. Étant donné que Chrome l'envoie, tout changement est hautement improbable.

@ ChrisBrownie55, je dirais que cela n'a aucun sens que cette fonctionnalité ne soit pas encore implémentée

On dirait que c'est en cours :
https://github.com/microsoft/TypeScript/pull/30829
(qui attend apparemment sur https://github.com/microsoft/TypeScript/pull/30467)

D'accord, #30829 est sur le point d'être fusionné après rebase, modulo certaines fonctionnalités que nous souhaitons peut-être faire pour qu'il explose sur les méthodes de nom privé.

Les gars, ce n'est pas parce qu'un navigateur majeur a implémenté la fonctionnalité (pour voir comment ça se sent, jouer avec, etc.) que tout le monde devrait le faire.

Il y a également eu des épisodes occasionnels de flux dans la discussion, donc je ne le considérerais toujours pas comme prêt pour les heures de grande écoute

Comme @isiahmeadows l'a mentionné, la proposition de champs de classe est pleine de controverse et beaucoup de gens ne l'

Si j'étais un implémenteur de langage, cela m'inquiéterait et je ne voudrais pas être responsable de la publication d'une fonctionnalité très détestée (gravée dans le marbre) parce que j'ai décidé de permettre à des milliers de développeurs (inconscients) de commencer à utiliser un problème fonctionnalité dans le code de production.

Les champs privés sont peut-être la plus controversée de toutes les fonctionnalités introduites depuis ES6. Je pense qu'il serait sage pour un implémenteur de langage de prendre en considération l'aversion avant d'aider à mettre la fonctionnalité dans le marbre.

@trusktr Cela peut être une fonctionnalité controversée, mais si les développeurs l'utilisent devrait être une décision laissée au développeur, pas aux outils. Un grand navigateur l'a expédié non pas pour "jouer avec" mais pour l'expédier pour une utilisation en production. Il a également été livré dans Node, le runtime JS côté serveur le plus populaire. Encore une fois, je suis moins inquiet de savoir si la syntaxe parvient ou non à TypeScript, mais plus de savoir si la syntaxe est prise en charge par le serveur de langage JavaScript sur VSCode (qui est soutenu par TypeScript).

Il a également été expédié dans Node

Uniquement comme effet secondaire de la version Chrome, qui maintient le moteur JS de Node.

Cela peut être une fonctionnalité controversée, mais si les développeurs l'utilisent devrait être une décision laissée au développeur, pas aux outils

Cela peut être le cas pour des développeurs comme vous (vous avez peut-être juste besoin de publier un produit, et vous travaillerez avec tous les outils dont vous disposez, ce qui est en fait ce que vous devriez faire à cet égard, et ce que font de nombreux développeurs employés).

Il existe également de nombreux développeurs qui ne connaissent peut-être pas les pistolets à pied associés aux champs de classe, tout en essayant simplement d'utiliser les outils qui leur sont fournis.

Et il y a aussi des développeurs qui se soucient du langage lui-même, et de l'avenir du code maintenable, et aimeraient le voir évoluer correctement, avant que certaines erreurs ne soient trop tardives pour être réparées.

La bonne chose est que, parce que les nouveaux champs privés utilisent la syntaxe # , il est encore possible de le corriger en utilisant le mot-clé private comme alternative.

TS doit-il vraiment suivre la norme à 100 % ? Nous savons déjà que le comité va contre la communauté avec thisGlobal ou #privateLol , alors peut-être est-il temps de dire que Google n'a pas le monopole de JavaScript avant qu'il ne soit trop tard ?

@TeoTN Les champs privés ne sont pas une affaire de Google. Il est passé par le TC39, comme toutes les autres normes récentes.

Quelques points pour aider à clarifier:

  • Nous ne sommes pas pressés d'expédier des fonctionnalités ES qui ne sont pas encore entièrement préparées (voir aussi : chaînage facultatif, fusion nulle, expressions de lancement, opérateur de pipeline, nom de, etc.)
  • Inversement, la mise en œuvre des fonctionnalités ES ratifiées et expédiées n'est pas facultative
  • Beaucoup de gens n'aiment pas certaines choses n'est pas un facteur de toute façon
  • Les champs privés seront dans TS lorsque nous pensons qu'il est sûr pour nous de les implémenter sans modifications de conception (ou révocations) ultérieures causant de graves problèmes à l'utilisateur

@RyanCavanaugh Merci pour la clarification et aussi pour tout le travail formidable ! Une petite suggestion : les ES évoluent en permanence et de nombreuses fonctionnalités sont en cours de travail, je pense qu'il est bon d'avoir une règle indiquant à quelle étape - Étape 4 ? Étape 3 ? ou quelque part entre les deux ? - Les fonctionnalités ES sont éligibles pour l'inclusion. Sinon, ce genre de discussion pourrait se répéter encore et encore à l'avenir pour d'autres fonctionnalités.

On peut raisonnablement dire que les champs privés sont entièrement cuits.

@kkimdev Stage 4 est aussi loin qu'il va; cela signifie être devenu une partie de la norme.

Fonctionnalités ES qui ne sont pas entièrement cuites

Curieux, quelles sont les fonctionnalités ES entièrement cuites ? Que signifie « entièrement cuit » dans cet exemple ?

la mise en œuvre des fonctionnalités ES ratifiées et expédiées n'est pas facultative

C'est tout à fait raisonnable étant donné que l'objectif de TypeScript est d'être simplement des types sur vanilla JS (donc des choses comme namespace étaient un mauvais choix par rapport aux objectifs actuels, et enum est également discutable).

TypeScript a le pouvoir d'aider (ou de ne pas aider) la communauté à faire évoluer les spécifications linguistiques, en attendant (ou n'attendant pas) la livraison d'une fonctionnalité jusqu'à ce que tous les principaux moteurs aient livré à l'unanimité la fonctionnalité donnée.

Cela semble inefficace, puisque les membres de l'équipe TS siègent sur TC39, ils ont donc déjà fait partie d'un consensus pour une fonctionnalité en phase 3 avant que quiconque ne l'ait expédiée en premier lieu - celle-ci incluse.

J'apprécie vraiment les décisions de conception de TypeScript pour être prudentes dans ce qu'ils expédient ; dans de nombreux cas, il est logique d'attendre un peu plus longtemps afin de garantir une stabilité aux développeurs. J'ai été très satisfait des décisions politiques concernant les champs privés, et en contact fréquent avec @DanielRosenwasser à leur sujet. L'équipe TypeScript a fourni de nombreux commentaires utiles à TC39 au fil des ans, ce qui a contribué à façonner la conception de nombreuses fonctionnalités.

Je pense que le meilleur endroit pour discuter de ces décisions de conception de langage serait dans les référentiels de propositions, dans les réunions du TC39 et dans d'autres contextes dédiés à ce travail. Nous y avons longuement discuté des propositions de champs privés et de méthodes avec @trusktr ; la discussion ici semble hors sujet.

En fin de compte, je pense que TC39 est l'endroit où nous devrions continuer à faire la conception du langage, et le référentiel TypeScript pourrait être un endroit pour discuter d'autres aspects, tels que la priorité et les détails d'implémentation d'une fonctionnalité, et le jugement du moment où une fonctionnalité est assez stable pour être expédié.

Étant donné que TypeScript Intellisense alimente la mise en évidence de la syntaxe JavaScript dans VS Code et les deux problèmes de mise en évidence de la syntaxe que j'ai trouvés (Microsoft/vscode#72867 et Microsoft/vscode#39703) dans la redirection du référentiel VS Code ici - où l'implémentation de ceci dans TypeScript est discutée - permettez-moi de contribuer en disant que ce serait cool que cela ne soit pas une erreur dans les fichiers JavaScript.

JavaScript parfaitement valide est marqué comme erroné dans VS Code car un compilateur pour un langage différent est en train de décider si la syntaxe sera prise en charge ou non. :-)

Je n'ai aucun problème à ce que TypeScript prenne son temps avant de prendre une décision à ce sujet (en fait, je le supporte !), mais cela affecte la mise en évidence de la syntaxe JavaScript d'une manière qui ne peut pas être facilement corrigée ou utilisée même localement (dans la mesure où Je sais) en corrigeant le fichier de grammaire du surligneur de syntaxe, car il n'y en a pas à corriger (AFAIK).

Bien que je ne fasse pas partie de l'équipe TypeScript, ils travaillent activement à sa mise en œuvre et je ne pense pas qu'il y ait beaucoup de doute à ce stade que les champs privés seront pris en charge. Voir https://github.com/microsoft/TypeScript/pull/30829.

Je peux confirmer que cela est en cours d'élaboration - nous collaborons avec l'équipe TS et sommes actuellement en train de terminer un rebase. Excité pour les champs à nom privé dans TS (et, par extension, Language Server).

Un grand merci à nos collaborateurs de Bloomberg pour l'avoir mis en œuvre sur https://github.com/microsoft/TypeScript/pull/30829 !

Salut. Si vous souhaitez que je crée un problème séparé pour cela, dites-le. Je suis intéressé à savoir quelle est la raison d'être de l'émission du #private PropertyDeclaration spécial qui a conduit à ce problème .

Par exemple, les déclarations suivantes seront générées :

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

...Compte tenu de l'entrée :

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

J'essaie de comprendre d'abord pourquoi il doit être là, mais aussi s'il peut être omis, étant donné que je construis des outils autour de la génération de déclarations.

J'essaie de comprendre d'abord pourquoi il doit être là, mais aussi s'il peut être omis, étant donné que je construis des outils autour de la génération de déclarations.

La présence d'un private rend la classe nominale dans notre analyse, il est donc important de le préserver dans un fichier de déclaration. Vous pourriez peut-être utiliser un outil de transformation de déclaration post-émission comme dts-downlevel pour réduire le niveau de la déclaration privée pour les anciens TS d'une manière ou d'une autre ? (Je ne sais pas encore s'il y a un downlevel pour #privates)

Pour ajouter à ce que Wesley a dit : downlevel-dts convertit #private en modificateur private , pour la compatibilité avec les anciennes versions de TypeScript.

La présence d'un privé rend la classe nominale dans notre analyse, il est donc important de préserver cela dans un fichier de déclaration

Pouvez-vous expliquer comment cela rend la classe nominale ? 🙂 Étant donné plusieurs propriétés privées, #foo et #bar , une seule déclaration ambiante spéciale #private sera ajoutée aux déclarations. Il n'y a aucun moyen d'analyser à partir des déclarations ni quels étaient les noms des propriétés privées ni combien il y en avait, car elles sont toutes remplacées par une seule déclaration de propriété #private . Je le comprendrais mieux s'il conservait les noms #foo et #bar . C'est un peu étrange, d'autant plus que LanguageService se plaint que la propriété #private n'est jamais utilisée. Cela ressemble à un bug pour moi. Mais dans tous les cas, les champs privés ne font pas partie des propriétés publiques du type et ne sont pas accessibles depuis l'extérieur de la classe, donc théoriquement je ne vois pas pourquoi ils devraient faire partie des déclarations ? Les mêmes principes ne devraient-ils pas s'appliquer que pour les champs et méthodes annotés avec d'autres Modificateurs d'accès que public dans lesquels ils ne sont pas du type KeyOf et ne font pas partie des déclarations ambiantes ?

Pour ajouter à ce que Wesley a dit : downlevel-dts convertit #private en modificateur private , pour la compatibilité avec les anciennes versions de TypeScript.

Cela ressemble à une bonne solution. Cependant, en faisant cela, quelle que soit la propriété que vous donnez au modificateur private ne fera pas partie du fichier .d.ts étant donné qu'elle ne fait pas partie des propriétés publiques du type. Je suis particulièrement intéressé par les déclarations, qui, même avec les exemples les plus simples, génèrent des diagnostics pour une propriété inutilisée appelée #private .

@wessberg J'ai signalé le bogue que vous avez remarqué concernant les avertissements de service de langue indésirables et je peux probablement mettre en œuvre une solution.

Concernant ton autre question :

Pouvez-vous expliquer comment cela rend la classe nominale ?

Quelqu'un a déjà ouvert un problème à ce sujet .

L'une des raisons de rendre quelque chose de nominal dans ces cas est que l'implémenteur de la classe peut maintenir un invariant caché parmi les champs privés : rendre les types structurels saperait cet objectif au moins sans des types vraiment fantaisistes qui peuvent exprimer des choses comme "la liste est toujours trié" ou "le diamètre est de 2 * le rayon".

Une autre raison est que le code comme ci-dessous devrait échouer à la vérification de type, car il n'y a aucun moyen de "faire la bonne chose" au moment de l'exécution :

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'

Hé les gars, je suis tellement content que nous ayons la syntaxe #private ! c'est génial !

mais je dois admettre que je suis vraiment déçu que nous n'ayons pas de syntaxe abrégée (voir proposition) , comme ceci :

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

je me demandais - pourrions-nous développer un plugin dactylographié ou une option tsconfig pour activer la syntaxe abrégée en tant que fonctionnalité expérimentale?

je meurs d'envie d'améliorer l'ergonomie, pour éviter autant this. répétitions inutiles de "experimentalPrivateShorthand": true ou quelque chose comme ça dans mes propres projets

cela peut-il être fait? peut-être qu'il y a une bonne raison pour laquelle ce n'est pas possible ? quel serait le travail impliqué? Tchin Tchin!

:vague: chasse

@chase-moskal TypeScript n'implémente rien d'autre que les types au-delà de la norme ECMAScript. La raison en est la sémantique changeante, comme le démontrent les champs privés et les décorateurs.

@chase-moskal Le moyen le plus pratique d'éviter de taper this tout le temps est honnêtement de lui attribuer un raccourci dans votre IDE (comme F3 par exemple). Beaucoup de choses sont possibles en forçant l'analyseur TS ou l'analyseur Babel et en écrivant des plugins, mais ils représentent tous beaucoup de travail et vous désynchroniseraient avec les outils officiels. Je me rends compte que votre question concernait bien sûr le soutien officiel, je pensais juste partager mes réflexions.

@jhpratt -

Honnêtement, je suis vraiment convaincu que je ne peux pas écrire de magnifiques cours minimalistes comme mes homologues utilisant babel le pouvaient il y a plus d'un an, et babel a même toutes les cloches et tous les sifflets dont je rêve !


@mbrowne - ce n'est pas vraiment la "capacité d'écriture" du code qui compte autant que la lisibilité , alors ne nous soucions pas de compter les pressions sur les touches. mon point est juste que javascript this répétition est trop souvent un encombrement indigne superflu

pensez maintenant à ceci pour la lisibilité : lorsque nous obtenons #private syntaxe abrégée this , vous sauriez instantanément que c'était pour accéder à un membre public - une énorme victoire pour lisibilité!


de toute façon, je viens de découvrir que le typescript ne prend pas encore en charge les méthodes privées

donc tout cela a juste besoin de plus de travail et de temps, apparemment de la part des gens de Bloomberg

sans méthodes privées pour faire correspondre les champs, nous avons juste besoin d'attendre (car personne ne mélangerait typescript-privates avec hashtag-privates dans la même classe sans devenir fou !)

c'est donc l'équipe de bloomberg qui modernise le tapuscrit ici, et ils ont également été impliqués dans les mêmes fonctionnalités de confidentialité pour babel il y a un an également ? ils font le travail de Dieu, et je suis curieux de savoir pourquoi ! continue comme ça! Tchin Tchin!

:vague: chasse

Oui, TypeScript vous a donné des décorateurs il y a des années. Devinez quoi? La sémantique a changé, grand moment. Désormais, TypeScript est bloqué dans un avenir proche pour prendre en charge l'API héritée, et cela provoquera une casse massive chaque fois qu'il sera décidé de la supprimer. Les fonctions fléchées font partie de la spécification ECMAScript, il est donc totalement hors de propos d'en parler.

TypeScript n'implémente actuellement aucune proposition ECMAScript avant d'atteindre l'étape 3. C'est là que vous devez obtenir le raccourci avant que TS ne soit intéressé.

Oui, TypeScript vous a donné des décorateurs il y a des années. Devinez quoi? La sémantique a changé, grand moment.

Nous vivons dans un monde pas idéal et certaines fonctionnalités sont nécessaires dès maintenant. Par exemple, la proposition des décorateurs est encore à l'étape 2, mais certains gros projets (Angular) les utilisent activement depuis longtemps. Autre exemple : ECMAScript ne spécifie pas protected modificateurs

Désormais, TypeScript est bloqué dans un avenir proche pour prendre en charge l'API héritée, et cela provoquera une casse massive chaque fois qu'il sera décidé de la supprimer.

D'autres langages introduisent également des fonctionnalités expérimentales sous les drapeaux du compilateur.

Je ne dis pas que TypeScript devrait implémenter chaque proposition sous l'étape 1 ou 2, mais de nombreuses propositions intéressantes pour TS sont restées bloquées, car il n'y a pas d'équivalents dans ECMAScript, par exemple https://github.com/microsoft/TypeScript/issues/2000

@ikokostya J'utilisais des décorateurs comme exemple de quelque chose où la sémantique a changé après que TypeScript les ait implémentés. Êtes-vous vraiment en train de dire que ce raccourci est « nécessaire en ce moment » ? Croyez-moi, nous pouvons gérer les cinq personnages supplémentaires. Si c'est si important pour vous, vous êtes libre de forker le compilateur.

TypeScript a été ferme sur ne rien implémenter avant l'étape 3, même sous un drapeau. Cela a été discuté en profondeur dans divers autres numéros précédemment.

Je ne vois rien d'autre que tourner en rond, donc je ne répondrai pas davantage à moins que quelque chose de notable ne survienne.

@jhpratt Mon propos ne concerne pas la sténographie. Merci de lire mon commentaire.

La suggestion concernant la fourchette n'est absolument pas pertinente.

Tout le monde n'est pas d'accord - et plus précisément, tout le monde au sein du comité TC39 n'est d'accord - que le raccourci rendrait le code plus lisible ou intuitif. Il y a eu beaucoup de discussions à ce sujet, et la syntaxe abrégée a été déplacée vers une proposition distincte en raison de ces préoccupations. (Je n'y ai pas suffisamment réfléchi pour me faire une opinion précise, je fais juste un récapitulatif.) Si vous voulez faire avancer cette proposition, la façon de procéder est de fournir un retour d'information au TC39. Je suis sûr qu'il y a déjà beaucoup de travail impliqué dans le maintien de TS et la mise en œuvre de toutes les propositions qui ont atteint l'étape 3, il est donc difficile d'envisager que cela soit pris en compte pour TS à moins qu'il ne progresse davantage dans TC39.

mais je dois admettre que je suis vraiment déçu que nous n'ayons pas de syntaxe abrégée (voir proposition)

Ce raccourci serait incompatible avec la proposition de pipeline qui pourrait également utiliser # et il est déjà question de devenir une proposition de l'étape 2. Cela n'a vraiment aucun sens de mettre en œuvre des propositions aussi tôt et d'apporter ensuite des changements décisifs. À un stade aussi précoce, vous ne savez même pas quelle proposition gagnera.

Même s'il s'avère compatible, je peux penser à au moins quelques cas d'utilisation supplémentaires pour un opérateur de préfixe # qui sont plus utiles que d'être un raccourci pour taper 5 caractères supplémentaires.

… surtout quand une bonne partie du cas d'utilisation des champs privés n'est pas du tout sur this (par exemple, static isMe(obj) { try { obj.#x; return true; } catch { return false; } } , pour ne citer qu'un exemple).

@phaux — ce sont de très bonnes informations sur la sténographie par rapport au pipeline, merci !

@jhpratt

TypeScript a été ferme sur ne rien implémenter avant l'étape 3, même sous un drapeau.

assez juste, mais il faut souligner que les méthodes privées sont en fait l'étape 3 , mais il n'y a pas encore de support dactylographié - et regardez, j'aime beaucoup la proposition de sténographie, mais c'est juste esthétique - je suis en fait maintenant beaucoup plus déçu par le manque de méthodes privées et d'accesseurs en ce moment

Je suppose (prie) que l'équipe de Bloomberg continue le travail de Dieu ici sur dactylographié, comme elle l'a fait pour babel il y a un an ? si c'est le cas, alors nous devons vraiment être patients et nous asseoir bien :)

il me semble que le typescript était beaucoup plus compétitif avec babel et les navigateurs pour les fonctionnalités ecmascript, et maintenant c'est en fait trop conservateur - nous sommes dans une situation où babel et chrome avaient livré des champs privés (non signalés) pendant un an auparavant Bloomberg est venu nous sauver

Je suis mal à l'aise par la divergence rampante entre le dactylographe et les fonctionnalités de babel - mes amis de Babel ont écrit du code magnifiquement fluide l'année dernière, alors que je suis toujours ici en train de payer une pénalité dactylographiée - ils se moquent de moi !

j'ai adoré ce type de script utilisé pour offrir des drapeaux expérimentaux qui me permettaient de décider ce que je suis prêt à risquer de refactoriser à l'avenir pour m'acheter d'excellentes fonctionnalités - est-ce maintenant la position de typescript, qu'il est trop dangereux de laisser les développeurs décider de ces risques, et ce tapuscrit est maintenant ma nounou ?

de plus en plus, il semble que je puisse choisir des fonctionnalités impressionnantes ou des types statiques - mais je ne peux pas maintenant avoir le meilleur des deux mondes, donc il y a une dissonance cognitive croissante en moi

Je suis vraiment curieux de connaître la dynamique ici - si Bloomberg n'était pas intervenu comme un chevalier en armure brillante, combien de temps aurait-il fallu avant que les tapuscrits ne relèvent le défi eux-mêmes ? ou est-ce une expérience dactylographiée : "si nous évitons simplement ces nouvelles fonctionnalités... ou peut-être s'agit-il d'une collaboration bienveillante vraiment cool explorant de nouvelles pistes de financement et de soutien pour l'open source, et cela a été un peu plus lent que prévu ? ou peut-être la philosophie dactylographiée juste beaucoup plus conservatrice qu'elle ne l'était auparavant ? où en sommes-nous sur ce spectre ?

pour la mise en œuvre des fonctionnalités de l'étape 3, est-ce plutôt que le dactylographe manque de bande passante ou de priorité ?

désolé de déclamer, et hé, je n'essaie vraiment pas d'être grossier ou de porter des accusations sérieuses ici, je ne fais que lancer des pensées de mon point de vue extérieur. je ne suis qu'un utilisateur et je suis vraiment curieux de savoir comment les gens ici plus au courant pourraient réagir à ces images que j'ai peintes - discussion intéressante, je vous apprécie tous !

:vague: chasse

j'ai adoré ce type de script utilisé pour offrir des drapeaux expérimentaux qui me permettaient de décider ce que je suis prêt à risquer de refactoriser à l'avenir pour m'acheter d'excellentes fonctionnalités - est-ce maintenant la position de typescript, qu'il est trop dangereux de laisser les développeurs décider de ces risques, et ce tapuscrit est maintenant ma nounou ?

Il ne s'agit pas de vous nourrir. Il s'agit de ne pas vouloir passer du temps à implémenter des fonctionnalités qui deviendront inévitablement une charge de maintenance lorsque la sémantique changera dans la proposition. Ils ne veulent absolument pas passer du temps à trouver comment se réconcilier avec la sémantique modifiée lorsqu'ils sont en conflit avec l'implémentation de TS. Ils ont mieux à faire. Il y a encore une montagne de problèmes liés au type à résoudre, il est donc logique de consacrer leurs ressources limitées à cela, et de ne pas essayer de faire le travail de TC39 en plus de résoudre les problèmes du système de type.

Quant aux méthodes et accesseurs privés : ceux-ci ne sont pas non plus implémentés dans la V8. Les méthodes de classe et les champs d'instance sont différents, et ils ne peuvent pas simplement... basculer un commutateur pour les prendre en charge également. Cela prend du temps pour les mettre en œuvre et ils ont déjà les mains pleines de travail tel qu'il est et ils sont une petite équipe. De plus, la règle n'est pas seulement que la proposition doit être à l'étape 3 : ils disent aussi explicitement qu'ils veulent avoir une grande confiance dans la sémantique de la proposition pour qu'elle soit définitive. Bien que rare, la sémantique _peut_ changer à l'étape 3. La fonctionnalité n'est pas implémentée dans la V8 sans raison valable. Ne vous méprenez pas cependant; J'aimerais moi aussi voir cette proposition mise en œuvre et j'ai hâte de l'utiliser. Cependant, la mise en œuvre des propositions des étapes précédentes est une perte de temps et le temps de l'équipe TS est mieux dépensé ailleurs. Il existe d'innombrables propositions de Stage 2, 1 et 0 que j'aimerais utiliser _aujourd'hui_, mais je comprends pourquoi je ne peux pas encore les avoir. Patience mon ami.

Vous êtes également tout à fait capable d'utiliser babel, exclusivement, pour transpiler votre texte dactylographié, si vous préférez les options que babel met à votre disposition.

@0kku - vous dites donc que c'est juste un problème de bande passante/capacité, plutôt qu'un problème philosophique - l'arriéré de bogues est maintenant une priorité plus élevée que la mise en œuvre des fonctionnalités de l'étape 3, mais dans l'histoire antérieure de dactylographe, il y avait peut-être moins de bogues , et il était donc plus facile d'allouer de la capacité à des implémentations expérimentales ? Je peux acheter cette théorie, et notre réponse devrait être d'attendre ou de contribuer

@ljharb - oh maintenant, c'est très intéressant - est-il réellement possible d'exécuter dactylographié et babel ensemble de cette manière ? pour obtenir le meilleur des deux mondes ?

mais je ne vois pas comment le service de langue vscode ts pourrait toujours fonctionner sans imploser sur la syntaxe inconnue (comme les méthodes privées par exemple)? le manque d'intellisense mord une partie trop importante de la proposition de valeur dactylographiée - si intellisense doit être complètement désactivé, la stratégie est un non-starter

comment cela pourrait-il être réglé à plus long terme? Je suppose que si nous distinguions des erreurs de saisie spécifiques pour la syntaxe de chaque fonctionnalité expérimentale, et aussi, si un projet de saisie pouvait désactiver ces erreurs spécifiques au niveau de tsconfig - alors nous aurions une chance d'ouvrir la porte pour tirer parti à la fois des fonctionnalités de babel et des fonctionnalités de saisie en même temps - mec, ce serait vraiment cool, et assommer toute la classe de reproches... bravo !

:vague: chasse

@ljharb

Vous êtes également tout à fait capable d'utiliser babel, exclusivement, pour transpiler votre texte dactylographié

Je suppose que vous pouvez configurer un processus de vérification de type dans lequel vous transpilez uniquement les méthodes privées à l'aide de Babel (mais laissez les types sur tout le reste) et effectuez une vérification de type sur ce code avec tsc . (Le script de construction, pour les passes de vérification de type, utiliserait simplement Babel seul.) Mais vous devriez ignorer de nombreuses erreurs de syntaxe dans votre IDE - je pense que ce serait un problème pour la plupart des gens.

@chase-moskal Bien que ce que @0kku ait dit soit correct en général, je n'ai vu aucune raison de ne pas implémenter de méthodes privées dans TS à ce stade. Je pense que c'est plus que cette proposition a atteint l'étape 3 plus tard que les champs de classe, et les implémenteurs y travaillent toujours.

Si vous êtes curieux de savoir pourquoi nous ne souhaitons pas sauter sur les fonctionnalités expérimentales, veuillez voir l' énorme complexité clusterfoxtrot qui est --useDefineForClassFields . Nous avons implémenté très, très tôt les initialiseurs de propriétés de classe en supposant qu'aucune proposition TC39 possible avec une sémantique différente ne pourrait même exister de manière plausible, et nous nous sommes trompés.

Les décorateurs ont tendance à être dans le même bateau, et vous serez surpris si vous pensez que nous pouvons abandonner entièrement le support de l'ancienne sémantique. Plusieurs grandes entreprises ont construit de grands cadres bien adoptés autour d'elle ; il est tout à fait irréaliste que nous puissions dire "Eh bien, le nom du drapeau a commencé par experimental , vous auriez donc dû savoir que cette fonctionnalité prise en charge au cours des 5 dernières années pourrait disparaître et disparaître un jour".

Pour ces deux fonctionnalités, nous allons être obligés de maintenir deux chemins de code subtilement différents ici pour le reste de nos vies, et ça craint, mais c'est le compromis - nous sommes très déterminés à garder TypeScript build-to-build mises à jour possibles sans casser le comportement d'exécution de votre code ; ce compromis est invisible lorsqu'il est en votre faveur (par exemple, votre programme continue de fonctionner ), mais vous pouvez voir plus facilement l'inconvénient en termes d'adoption de fonctionnalités.

De notre point de vue, vous ne pouvez pas renoncer à la compatibilité d'exécution d'une version à l'autre, de la même manière que vous ne pouvez pas renoncer à toute responsabilité en cas de négligence.

Nous avons également retardé l'adoption précoce du chaînage optionnel malgré le recul MASSIF de la communauté - si j'avais un centime à chaque fois que quelqu'un disait "Eh bien, mets-le derrière un drapeau", je le taperais depuis un bateau. Mais c'était la bonne chose à faire, car nous aurions dû deviner ce que (null)?.prop produit, et nous aurions absolument deviné null (pas undefined ), et nous' d vivre avec un autre fardeau de complexité continue pour comprendre celui-là. Il y a un fort avantage contrefactuel ici pour le fait que personne n'est coincé assis sur une base de code de 3 millions de lignes remplies d'une utilisation de ?. où ils dépendent de cela produisant parfois null , sans aucun moyen de même comprendre comment passer aux différents comportements undefined .

Bloomberg a implémenté des champs privés car ils étaient très enthousiastes à l'idée d'avoir cette fonctionnalité et désireux de contribuer à TypeScript. S'ils n'avaient pas été dans cette situation, nous aurions implémenté la fonctionnalité nous-mêmes, comme tout le reste.

En général, je dirais que la chronologie de JavaScript est très, très longue et que, de manière réaliste, vous pouvez écrire du JavaScript bon et ergonomique en 2020 sans utiliser la syntaxe de 2024, tout comme vous pourriez écrire du JS bon et ergonomique en 2016 sans utiliser la syntaxe de 2020. Personne n'est bloqué par l'incapacité d'utiliser une syntaxe qui n'a même pas encore de sémantique définitivement décidée ; c'est juste une programmation imaginaire à ce stade.

Non seulement cela, mais il n'est même pas certain à 100% que la proposition de champs de classe actuelle et tous ses détails passeront à l'étape 4 dans sa forme actuelle (surtout maintenant qu'il y a une société membre du TC39 qui s'agite pour supprimer complètement la proposition et la remplacer avec un autre). Je suppose que 95% de certitude, mais en général, même la mise en œuvre d'une proposition de stade 3 n'est pas complètement sans risque. Cependant, la probabilité de nouveaux changements après l'étape 3 est très faible, donc je pense que la politique actuelle de TS est bonne.

maintenant qu'il y a une société membre du TC39 qui s'agite pour supprimer complètement la proposition [champs de classe] et la remplacer par une autre

Intéressant, pensez-vous à pointer un lien vers cela ?


Voici une idée : peut-être que l'équipe TS pourrait passer du temps à améliorer le système de plugins, pour donner aux auteurs de plugins une API claire qui se connecte à la fois à la compilation et au language-server-protocol intellisense-time. Cela permettrait aux tiers d'implémenter toutes les fonctionnalités expérimentales qu'ils souhaitent, y compris une nouvelle syntaxe, tout en ayant toujours une intelligence fonctionnelle dans les IDE et les éditeurs de texte.

La dernière fois que j'ai vérifié, ttypescript est le seul moyen de configurer les transformateurs TypeScript sans programmation dans tsconfig.json , et il ne se connecte à l'intellisense d'aucun IDE, donc la possibilité pour les tiers de créer des fonctionnalités significatives qui s'intègrent bien avec les outils existants comme VS Code ne sont pas encore là. Nous ne voudrions pas abandonner notre belle expérience VS Code en passant à ttypescript et en ayant besoin de nous fier à la sortie du terminal alors que VS Code est incapable de comprendre la syntaxe et de générer des erreurs.

Ensuite, TypeScript pourrait se concentrer sur les fonctionnalités stables et laisser des tiers créer ou utiliser des fonctionnalités expérimentales risquées (aussi simple que cela soit dans l'écosystème Babel).

Intéressant, pensez-vous à pointer un lien vers cela ?

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

Il y a un ensemble très limité de choses syntaxiques que vous pouvez faire avec un plugin Babel ; fondamentalement, l'analyseur doit déjà le prendre en charge. L'expression do "plugin", par exemple, nécessite toujours une logique au cœur de Babel lui-même : https://github.com/babel/babel/blob/master/packages/babel-parser/src/parser /expression.js#L991 Ce n'est vraiment pas différent d'un commutateur de ligne de commande.

Existe-t-il un problème qui peut être suivi pour les méthodes de classe privée et les accesseurs ?

@RyanCavanaugh

Pour ces deux fonctionnalités, nous allons être coincés à maintenir ici deux chemins de code subtilement différents pour le reste de notre vie.

Je ne pense pas que ça devrait se passer comme ça et j'imagine que ça fait mal à toute la communauté. Si les décorateurs atteignent le stade 3, je pense qu'il est raisonnable de leur laisser du temps pour passer à la nouvelle version des décorateurs. Peut-être prendre en charge les deux pendant un certain temps, peut-être faire un changement dur et supprimer les décorateurs hérités dans TypeScript 4+. Je ne connais pas la différence entre les anciens et les nouveaux décorateurs, car je ne les utilise pas (enfin, fonctionnalité expérimentale). Mais je pense que les projets concernés devraient travailler sur la proposition, si la proposition ne répond pas à leurs besoins. C'est mieux pour tout le monde. TypeScript n'est pas le bon endroit pour déclencher la guerre à propos des fonctionnalités héritées et expérimentales.

Je regrette d'avoir atterri ici :/

@RyanCavanaugh

Il y a un ensemble très limité de choses syntaxiques que vous pouvez faire avec un plugin Babel ; fondamentalement, l'analyseur doit déjà le prendre en charge.

Vrai. Mais dans l'intérêt de la comparaison avec TypeScript, dans Babel, vous pouvez simplement forker l'analyseur et configurer votre babel.config.js pour utiliser l'analyseur personnalisé et tous les plugins de syntaxe personnalisés que vous créez. Oui, c'est beaucoup de travail (surtout apprendre à ajouter une nouvelle syntaxe pour la première fois), mais je ne connais aucune option équivalente pour TS, et bien sûr, dans Babel, il est beaucoup plus facile d'écrire des plugins de transformation basés sur la syntaxe existante. Je ne sais pas quel est l'état actuel des options de personnalisation dans TypeScript, mais la dernière fois que je l'ai examiné il y a quelques années, il semblait qu'il n'y avait pas d'autre option pour l'étendre que de tout bifurquer.

Le hachage pour les privés IMO est moche et déroutant. C'est difficile à appliquer car il n'y a aucun moyen de les mettre en œuvre autrement. Il n'y a pas d'étape de construction comme dans TS. L'effet est qu'il ne fait qu'encombrer le code avec des symboles pour le très petit gain d'un « privé dur » avec des gens pensant que c'est la « bonne » façon d'écrire du JS, car beaucoup de gens apprennent que les choses devraient simplement être privées par défaut.
Il aurait dû y avoir plus de propositions avant de les inclure dans la norme, surtout lorsqu'il y a eu un désaccord évident sur la question.

Les choses devraient simplement être privées par défaut. On leur apprend que toute chose doit être accessible par la réflexion, ce qui n'est en fait une bonne chose pour personne.

@ljharb Oui, ils devraient. Cependant, lorsque la façon de déclarer un privé consiste à lancer des symboles de hachage devant les variables, la manière «correcte» de créer une classe en JS consiste à apprendre aux gens à simplement mettre des hachages devant les variables membres. Pas seulement lors de leur déclaration, mais aussi lors de leur référencement. C'est particulièrement déroutant si vous venez d'autres langues. Ma première pensée en voyant quelque chose comme this.#x = this.#something(); et une déclaration dans une classe était que le hachage faisait partie de la variable elle-même. Je n'aurais jamais deviné que c'était un modificateur. Le trait de soulignement pour le public, qui semble à l'envers aussi. Ce n'est pas vraiment pertinent pour TS, mais juste une diatribe agaçante, je suppose.

Oui, apprendre de nouvelles choses quand on est cimenté dans la familiarité peut être un ajustement. J'ai confiance que la communauté JS continuera à apprendre !

(le hachage fait partie de la variable elle-même, le nom de this.#x n'est pas "x, mais private", mais en fait, #x , une valeur unique dans cette portée lexicale)

Oui, apprendre de nouvelles choses quand on est cimenté dans la familiarité peut être un ajustement. J'ai confiance que la communauté JS continuera à apprendre !

La façon dont vous le dites, on dirait que si cela apprenait quelque chose qui ajoutait à notre sagesse de programmation, alors que ce n'est qu'une autre bizarrerie de JS que l'on doit mémoriser :D

Cette page vous a été utile?
0 / 5 - 0 notes