Typescript: Vorschlag für private Felder implementieren

Erstellt am 26. Juli 2016  ·  134Kommentare  ·  Quelle: microsoft/TypeScript

Ich denke, es wäre schön, den Vorschlag für private Felder der

Derzeit enthält der Vorschlag nur private _Eigenschaften_, aber Methoden werden wahrscheinlich folgen. Der wichtigste Teil des Vorschlags ist außerdem, dass private Eigenschaften nur innerhalb der Klasse selbst verfügbar sind.

Committed Fixed Suggestion

Hilfreichster Kommentar

Ich glaube nicht, dass die Leute mit einer nicht "privaten" Keyword-basierten Lösung zufrieden sein werden.

Alle 134 Kommentare

Was hält das TypeScript-Team von der Syntax und der Verwendung eines Symbol-/Zeichenpräfixes?

Ich persönlich finde, dass es schrecklich aussieht, aber anscheinend gibt es technische Einschränkungen (die Verwendungen müssen die Sichtbarkeit identifizieren, aus Gründen, die ich nicht vollständig verstehe).

Es wäre traurig zu sehen, dass TypeScript die aktuelle private/geschützte Syntax verliert, die viel sauberer ist und mit einer Reihe anderer Sprachen konsistent ist. Ist dies wahrscheinlich? Gibt es Alternativen?

Darüber hinaus gibt es Gespräche darüber, die Symbole # und @ umzutauschen (dh die Verwendung von # für Dekoratoren), was offensichtlich auch Auswirkungen auf TypeScript hätte .

Ich finde es auch "schrecklich". Ich denke, wie der Bind-Operator :: , der es nicht wirklich weit gebracht hat, lohnt es sich, ihn zu implementieren, bis er mit T39 ein bisschen weiter geht. Ich vermute sehr, dass es ein bisschen anstrengend wird. Außerdem wird das Down-Emit zur Unterstützung eher schwierig sein, vermute ich, da jede Zugriffsseite neu geschrieben werden muss.

die Verwendungen müssen die Sichtbarkeit identifizieren, aus Gründen, die ich nicht vollständig verstehe

Hauptsächlich, weil Sie auf der Verwendungsseite identifizieren müssen, wie die Eigenschaft gesucht werden soll, da sie einen anderen Lookup-Algorithmus benötigt, damit untergeordnete Klassen dieselben privaten Namen wiederverwenden können, ohne die privaten Eigenschaften der Vorfahren "wissen" zu müssen.

Ein Vorteil der vorgeschlagenen Syntax besteht darin, dass Sie this weglassen und einfach #field direkt verwenden können. Außerdem kann das Siegel mit Dekorateuren ausgetauscht werden (https://github.com/tc39/proposal-private-fields/issues/32) und stattdessen würde @ verwendet, also würden Sie @field , genau wie Ruby. Findest du diese Syntax immer noch hässlich?

Ich glaube nicht, dass die Leute mit einer nicht "privaten" Keyword-basierten Lösung zufrieden sein werden.

Ich sehe keine gute Möglichkeit, dies zu tun, während allgemeines eval wie es JavaScript tut - ein konkretes Token ermöglicht eine gewisse Differenzierung und ermöglicht es, private Zustände zu unterstützen, die nicht auf einem statischen Typsystem wie in TypeScript basieren . Wir haben unter https://github.com/tc39/proposal-private-fields/issues/14 eine Reihe von Syntaxalternativen besprochen, und ich sehe die aktuelle Syntax von TypeScript nicht als etwas, das in einem immer ordnungsgemäß funktionieren kann vollständig allgemeine JS-Umgebung.

Hauptsächlich, weil Sie auf der Verwendungsseite identifizieren müssen, wie die Eigenschaft gesucht werden soll, da sie einen anderen Lookup-Algorithmus benötigt, damit untergeordnete Klassen dieselben privaten Namen wiederverwenden können, ohne die privaten Eigenschaften der Vorfahren "wissen" zu müssen.

Ich wünschte, ich wüsste mehr darüber, wie JavaScript intern funktioniert. Ich dachte, es würde so funktionieren, wie es hier und hier beschrieben ist , aber anscheinend nicht. Ich finde es immer noch schwer zu glauben, dass das einen signifikanten Einfluss auf die Leistung haben würde, aber es gibt keine Vergleichszahlen.

Findest du diese Syntax immer noch hässlich?

Im Wesentlichen ja. Mehr noch, ich finde es sowohl inkonsistent mit dem Rest der JavaScript-Syntax als auch inkonsistent mit vielen anderen Sprachen:

| Sprache | Syntax | Anmerkungen |
| --- | --- | --- |
| C# | privates int x; | |
| C++ | Privatgelände:
intx; | |
| Java | privates int x; | |
| PHP | privat $x; | |
| Python | __x | "kein Kommentar" |
| Rubin | Privatgelände
def-Methode
# ...
Ende | Es ist eine Methode, aber Felder sind privat
standardmäßig denke ich. |
| TypeScript | privat x; | |
| Visual Basic | Privat x Als ganze Zahl | |

Alle bis auf _eine_ der oben genannten Sprachen verwenden das Schlüsselwort private , und es scheint, dass Python sowieso nicht wirklich einen "richtigen" privaten Status hat.

Mit Ausnahme von Python (wieder) formatiert keine der Sprachen Felddeklarationen oder Feldzugriffe je nach Sichtbarkeit unterschiedlich, und sie alle ermöglichen neue Sichtbarkeitsmodifikatoren, falls dies jemals erforderlich ist.

Ich habe auch das Gefühl, dass sowohl # als auch @ für Dinge wie Dekorateure besser funktionieren, die ( in Kevins Worten ) "syntaktisch 'außerhalb' des imperativen Flusses" sind.

Ich sehe keine gute Möglichkeit, dies zu tun, während die allgemeine Auswertung wie bei JavaScript unterstützt wird

Wäre es möglich, dieses Problem laienhaft zu erklären? (vielleicht in https://github.com/tc39/proposal-private-fields/issues/14)

Es wäre schön, eine Liste dieser Probleme mit Beispielen an einer Stelle zu haben, damit es etwas gibt, auf das man sich beziehen kann.

Ich finde es immer noch schwer zu glauben, dass das einen signifikanten Einfluss auf die Leistung haben würde, aber es gibt keine Vergleichszahlen.

Das wäre es, wenn Sie möchten, dass es wirklich privat ist und nicht nur eine Konvention, wie es in TypeScript der Fall ist. Wann immer Sie eine Eigenschaft in JavaScript nachschlagen, ist der Vorgang im Wesentlichen wie folgt:

  1. Siehe Beispiel für eigenes Eigentum.
  2. Wenn kein eigenes Grundstück vorhanden ist, schauen Sie sich den Prototyp für das eigene Grundstück an.
  3. Steigen Sie die Prototypkette auf, bis keine Eigenschaft gefunden wurde.
  4. Wenn gefunden, handle mit Eigenschaftsdeskriptor (beschreibbar, get, set, konfigurierbar)
  5. Wenn nicht gefunden und gelesen, geben Sie undefined oder schreiben Sie, setzen Sie den Wert als eigene Eigenschaft, wenn er nicht versiegelt oder eingefroren ist.

Mit Privaten ohne Muster im Namen hätten Sie keine eigenen Eigenschaften, Sie hätten so etwas wie eigene private Eigenschaften, die nicht in einer Prototypkette aufsteigen würden. Diese müssten Sie dann auch dort für jede Operation suchen, die möglicherweise auf die privaten Eigenschaften zugreifen könnte, da Sie nicht sicher sind, auf welche verwiesen wird. Das Nachschlagen auf normale Weise und dann nur, wenn es nicht in Privaten gefunden wird, könnte sehr gefährlich sein, denn was ist, wenn Sie etwas in der Prototypen-Kette finden, es aber auch eine private Version gibt?

Die größte Herausforderung besteht darin, dass JavaScript-Klassen immer noch eine falsche Bezeichnung sind. Sie sind im Wesentlichen syntaktischer Zucker für prototypische Vererbungskonstruktorfunktionen. Mir ist ein Gedanke gekommen, den ich versuchen werde, zu tc39/proposal-private-fields#14 hinzuzufügen.

Wäre es möglich, dieses Problem laienhaft zu erklären?

Wenn die Anruf-Site neu geschrieben werden muss, können Sie Dinge wie die folgenden niemals unterstützen:

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

Oder jede Verwendung von eval ähnlichen Strukturen. Sie könnten sich dafür entscheiden, Dinge wie den Indexzugriff für Privatpersonen oder keine Evaluierungsunterstützung zu unterstützen, aber dann "warum sich die Mühe machen". Auf so ziemlich alles wurde in dem dortigen Vorschlag auf die eine oder andere Weise hingewiesen, aber die Leute sind immer noch "aber ich mag privat" 😁.

du hättest keine eigenen Immobilien, du hättest so etwas wie eigene private Immobilien

Wenn Sie einen einzelnen Satz von Eigenschaften mit einem visibility Element im Deskriptor hätten, besteht das Problem vermutlich darin, dass Sie nicht wissen würden, ob Sie aufsteigen sollen, wenn die Eigenschaft im aktuellen Objekt nicht vorhanden wäre Prototyp-Kette.

Wenn die Anrufseite neu geschrieben werden muss, können Sie Dinge wie ...

AFAIK, das wird sowieso nicht unterstützt ( ref ).

Ich verfolge den Bewertungsfall immer noch nicht wirklich. Ich dachte, dass die Eigenschaftsprüfungen zur Laufzeit stattfinden würden, nachdem die Eigenschaftsnamen berechnet wurden.

aber die Leute sind immer noch "aber ich mag privat"

Ich versuche, nicht einer dieser Leute zu sein und die Probleme zu verstehen, aber die vorgeschlagene Syntax ist mir einfach unangenehm. =)

Okay, ich glaube, ich verstehe jetzt den Fall eval/rewrite. Verwendungswebsites innerhalb der Klasse würden umgeschrieben, um die Sichtbarkeit basierend auf den deklarierten Eigenschaften anzuzeigen, und dies wäre nur möglich, wenn es sich um einfache Lookups handelt.

Wenn Sie einen einzelnen Satz von Eigenschaften mit einem Sichtbarkeitselement im Deskriptor hätten, besteht das Problem vermutlich darin, dass Sie nicht wissen, ob Sie in der Prototypkette aufsteigen sollen, wenn die Eigenschaft im aktuellen Objekt nicht vorhanden wäre.

Hmm. Aber wenn es in der aktuellen Klasse nicht existiert, ist es dann nicht per Definition nicht privat? Wenn dies der Fall ist, müsste es sowieso in der Prototypenkette nach oben rücken (wie bei regulären Suchvorgängen nach öffentlichem Eigentum). Für den Zugriff auf private würde keine zusätzliche Arbeit anfallen.

(Ich übersehe möglicherweise etwas Offensichtliches)

Aber wenn es in der aktuellen Klasse nicht existiert, ist es dann nicht per Definition nicht privat? Wenn dies der Fall ist, müsste es sowieso in der Prototypenkette nach oben rücken (wie bei regulären Suchvorgängen nach öffentlichem Eigentum).

Nein, du willst nicht aufsteigen. Private Labels werden nicht vererbt und Unterklassen können Privates wiederverwenden, ohne sich über Maskierungs-/Namenskollisionen Gedanken machen zu müssen.

@glen-84 Beide von Ihnen erwähnten Beiträge weisen auf Probleme mit dem nicht signierten privaten Zustand hin. Haben Sie Ideen für Lösungen für diese Probleme? Ich denke, die Verkomplizierung der Lookup-Kette wäre in Bezug auf die Kompatibilität riskant, erschwert die Implementierung von JavaScript mit guter Leistung (möglicherweise verlangsamt vorhandene Programme), wäre im Grunde unmöglich mit Proxys zu quadrieren und würde im Allgemeinen das mentale Modell der Sprache erheblich komplizieren (was hat bereits ein relativ komplexes Objektsystem).

Im sprachübergreifenden Vergleich erwähnen Sie Ruby. Ich denke, Ruby ist ein gutes Beispiel für einen privaten Staat _mit_ einem Siegel-- @ . Sie können Getter- und Setter-Methoden ohne Siegel aufrufen.

Nein, du willst nicht aufsteigen. Private Labels werden nicht vererbt und Unterklassen können Privates wiederverwenden, ohne sich über Maskierungs-/Namenskollisionen Gedanken machen zu müssen.

Ich meinte, aufzusteigen, wenn die Eigenschaft nicht in der aktuellen Klasse war, um nach einer öffentlichen oder geschützten Eigenschaft zu suchen.

Beide Posts, die Sie erwähnt haben, weisen auf Probleme mit dem Privatstaat ohne Siegel hin. Haben Sie Ideen für Lösungen für diese Probleme?

Das ist für mich als jemand ohne Verständnis für die interne Funktionsweise von JavaScript sehr schwierig.

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

Ich habe keine Ahnung, was das bedeutet. Wofür ist das? Ist es unmöglich zu tun?

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.

So stark optimiert, dass ein einziger Schalter für die Sichtbarkeit die Leistung erheblich beeinträchtigen würde?

Would for-in enumerate over these properties?

Ich denke, es würde vom Kontext abhängen. Innerhalb derselben Klasse, ja. Dies ist jedoch kein Grund, private , sondern ein Implementierungsdetail, und andere Sprachen haben solche Fragen wahrscheinlich bereits beantwortet.

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

Wahrscheinlich ja (Sichtbarkeit wird erhöht) zur ersten Frage und nein zur zweiten. Auch dies wurde alles schon einmal gemacht, nicht wahr?

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.

Sichtbarkeit ist nur ein Werkzeug zur Kapselung und Definition einer öffentlichen Schnittstelle. 99% der Entwickler interessieren sich wahrscheinlich nicht für "Informationslecks". Das heißt, ich habe zwei getrennte Funktionen vorschlagen hier . Vielleicht könnte dieser Vorschlag anders genannt werden, wie "versteckter Zustand" oder "sicherer Zustand" und ermöglichen, dass etwas wie privater / geschützter Zustand anders implementiert wird.

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

Verwenden Sie "versteckter/sicherer Zustand", wenn Sie eine Perf. :D Im Ernst, von welcher Art von Leistungsverlust reden wir? Vielleicht kann jemand einen Prototyp erstellen. =)

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

Wären selbst-hosting-integrierte Inserate (wenn ich überhaupt verstehe, was das bedeutet) nicht wirklich schlecht für die Leistung? Wenn nicht ... verwenden Sie "hidden/secure state" und keine übergeordnete private/geschützte Sichtbarkeit.

Ich denke, es wäre in Bezug auf die Kompatibilität riskant, die Lookup-Kette zu komplizieren

Ich bin nicht der erste/einzige, der denkt, dass es so funktionieren könnte/könnte. Sie greifen auf eine Eigenschaft zu, sie sucht nach einem Deskriptor nach Sichtbarkeit und reagiert entsprechend. Es scheint nicht kompliziert zu sein, wenn Sie keine Ahnung haben, wie die Dinge in JS wirklich funktionieren. Ich muss wirklich einen Crashkurs über JS-Interna/Property-Lookup-Algorithmen lesen. =P

Ich denke, Ruby ist ein gutes Beispiel für einen privaten Staat mit einem Siegel--@

Ruby ist nicht einmal eine Sprache der C-Familie, und es scheint keine öffentlichen Felder zu geben, sondern nur Getter und Setter (Accessoren). Der aktuelle Vorschlag für einen privaten Staat hat mehrere Deklarationen nebeneinander mit demselben allgemeinen Zweck (Deklaration von Eigenschaften), aber sichtlich unterschiedlichen und inkonsistenten Syntaxen.

Nach alledem bin ich hier weit überfordert und füge höchstwahrscheinlich mehr Lärm als Wert hinzu, also werde ich versuchen, Stillschweigen zu bewahren und die Experten zu einem Konsens kommen zu lassen.

Ich werde diesen Wunsch mit TC39 besprechen und wir werden sehen, ob wir noch andere Ideen haben, wie man ein Präfix vermeiden kann. Ich persönlich habe keine. Beachten Sie, dass, wenn TypeScript beschließt, private Felder zu implementieren, diese sich in TC39 noch in Phase 1 befinden und daher Änderungen unterliegen können.

Was hält das TypeScript-Team von der Syntax und der Verwendung eines Symbol-/Zeichenpräfixes?

Ich persönlich finde es schrecklich...

Hinweis Ich habe einen Vorschlag gemacht , um die schreckliche # Syntax loszuwerden.

@shelby3 Leider eval interagiert; Ohne ein Siegel wird alles "zu dynamisch", um richtig zu funktionieren.

@littledan Ich habe es jetzt weiterverfolgt und mein stärkstes Argument gegen die Verwendung eines Siegels und mein Argument zur Maximierung der Kompatibilität mit TypeScript vorgebracht . Ich verstehe jetzt jedoch, warum wir die Privatsphäre für nicht typisierte Argumente von Methoden deklarieren müssen.

@isiahmeadows

Es wird größtenteils die aktuelle pseudo-private Implementierung ersetzen [...] Außerdem ist der wichtigste Teil des Vorschlags, dass private Eigenschaften nur innerhalb der Klasse selbst verfügbar sind.

Ich hoffe, es wird nicht die pseudo-private Implementierung ersetzen. Ich denke, die Verfügbarkeit nur innerhalb einer Klasse ist eigentlich keine so gute Sache (da Sie mit Verfügbarkeit die Zugänglichkeit meinen). Ich gebe zu, es kann besondere Situationen geben, in denen es sinnvoll ist, streng private und unzugängliche Eigenschaften zu haben, zB aus Sicherheitsgründen. Ich gebe auch zu, dass es für Leute, die mit anderen Sprachen vertraut sind, offensichtlich verwirrend ist, dass private in JavaScript eigentlich nicht so privat ist. Aber abgesehen von Sicherheitsgründen sollten meiner Meinung nach die meisten Entwickler private meiste Zeit nur verwenden, um einen Vertrag zu definieren, aber nicht um die Zugänglichkeit zu kontrollieren.

ZB aus Sicht der Architekten finde ich das TS private -Stichwort und seine pseudo-private Natur sehr gut

  • dass es erlaubt, den Vertrag der Schnittstelle eines Typs auszudrücken und wie sie von Clients verwendet werden soll
  • dass der Vertrag zur Compilezeit vom TS-Compiler geprüft wird
  • dass ich den Vertrag zur Laufzeit noch bewusst "verletzen" kann, insbesondere bei Whitebox-Unit-Tests.

Die Zugänglichkeit privater Eigenschaften zur Laufzeit trägt sehr zur Testbarkeit bei, da ich in der Lage bin, einen privaten Zustand in eine zu testende Klasse einzufügen, indem ich einfach ihre privaten Felder setze (in TypeScript empfehle ich die Klammernotation anstelle von any Umwandlungen aufgrund von besseren Refactoring-Unterstützung), zB:

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

Es ist kein komplizierter Testcode erforderlich, nur um eine Klasse mit einem bestimmten (privaten) Status einzurichten.
Ein weiterer Vorteil von pseudo-privaten Eigenschaften besteht darin, dass sie für das Affen-Patching unerlässlich sind.

Ich glaube nicht, dass die TypeScript-Community gerne alle ihre private variable Zeilen in private #variable ändern würde.

Aus der TypeScript-Perspektive sind die meisten von uns mit unseren schönen, süßen Illusionen einer guten Sprache zufrieden (Intelligenz, Build-Time-Fehler, Typen, verschiedene Zuckerarten). Diese Illusionen geben uns eine bessere Entwicklungserfahrung, wir schreiben schneller besseren Code. Dies ist der Hauptgrund, warum wir TS neben der ESNext-Transpilation verwenden - aber für letztere gibt es Babel und das ist besser (oder zumindest war es besser, als ich das letzte Mal nachgesehen habe).

Ich spreche nicht von den wenigen, die von privaten Variablen eigentlich mehr wollen als einen syntaktischen Zucker in ihren Quelldateien. Ich denke, diese Jungs brauchen etwas Stärkeres, vielleicht näher am nativen Code.

Aber für den Rest wir: JS privat brauchen wir nicht wirklich. Wir brauchen die einfachen, einfachen private convenient Variablen, wie wir sie in C++, Java, C# usw. verwendet haben.

Bitte stimmen Sie für eine Lösung, die uns nicht schmerzt. Vielleicht sanft privat? Weil ich bezweifle, dass wir das Siegel privat #variable . Oder wären TS private und ES private unterschiedliche Konzepte? Hässlich.

@igabesz

Ich glaube nicht, dass die TypeScript-Community gerne alle ihre private variable Zeilen in private #variable ändern würde

Eigentlich wäre mit diesem Vorschlag private unnötig. Stattdessen ersetzt das Siegel # es völlig konfliktfrei.

Aber für den Rest wir: JS privat brauchen wir nicht wirklich. Wir brauchen die einfachen, einfachen privaten bequemen Variablen, wie wir sie in C++, Java, C# usw. verwendet haben.

Das private von TypeScript ist weich privat, wie das der meisten OO-Sprachen. Sogar die privaten Variablen von Java sind technisch immer noch weich-privat, da sie immer noch mit einer Fluchtluke zugänglich sind. JS private entspricht der Verwendung einer Closure, mit der Ausnahme, dass Sie weiterhin auf den privaten Status von Nicht- this Instanzen zugreifen können.

Bitte stimmen Sie für eine Lösung, die uns nicht schmerzt. Vielleicht sanft privat? Weil ich bezweifle, dass wir die private #Variable des Siegels wollen. Oder wären TS privat und ES privat vielleicht unterschiedliche Konzepte? Hässlich.

Es wären unterschiedliche Konzepte, aber im Allgemeinen sind Fluchtluken in der Praxis selten nützlich. Die primäre Ausnahme besteht bei der Objektinspektion (zB Entwicklertools, Node.js util.inspect ), aber die meisten sind Host-definiert und verwenden bereits jetzt privilegierte native APIs, sodass es nicht dringend erforderlich ist, sie der Spezifikation hinzuzufügen.

Sobald ES den privaten Status standardisiert hat, wird TS diesen übernehmen und wahrscheinlich seinen eigenen Soft-Private-Mechanismus ablehnen, der in der nächsten Hauptversion entfernt wird. Es war schon immer eine strenge Obermenge von ES, und es hat im Laufe der Entwicklung von ES je nach Bedarf Funktionen hinzugefügt (asynchrone Funktionen), geändert (Klassen) und/oder veraltet ( /// <amd-dependency /> ), um sich selbst als strikt zu erhalten Superset und nicht die aktuelle Spezifikation duplizieren.

Sobald ES den privaten Status standardisiert hat, wird TS diesen übernehmen und wahrscheinlich seinen eigenen Soft-Private-Mechanismus ablehnen, der in der nächsten Hauptversion entfernt wird.

😭

Sobald ES den privaten Status standardisiert hat, wird TS diesen übernehmen und wahrscheinlich seinen eigenen Soft-Private-Mechanismus ablehnen, der in der nächsten Hauptversion entfernt wird.

Dies ist nicht die Position des TS-Teams. Wir haben nicht vor, irgendetwas in absehbarer Zeit einzustellen.
Wenn und wenn der private Statusvorschlag den richtigen Status erreicht, wird TS ihn implementieren. Ich glaube nicht, dass dies Auswirkungen auf Privatpersonen hat, da TS sie heute implementiert.

@mhegazy Okay. Ich stehe korrigiert. (Es war übrigens eine begründete Vermutung.)

Der Vorschlag für Klassenfelder befindet sich jetzt in Phase 2, daher bin ich froh, dass das TypeScript-Team dies durchdacht hat und bereit ist, den EcmaScript-Standards zu folgen 💯

Wenn und wenn der private Statusvorschlag den richtigen Status erreicht, wird TS ihn implementieren.

@mhegazy Ist Phase 3 der richtige Zeitpunkt für die Implementierung?

EDIT: Vielleicht habe ich meine Antwort gefunden

@styfle siehe die Diskussion aus den Notizen zum Designmeeting (#16415), in der die aktuellen Überlegungen zur Implementierung erörtert werden.

Ist Phase 3 der richtige Zeitpunkt für die Implementierung?

Jawohl. Wir beginnen, die verschiedenen Designs zu untersuchen, die für diese Funktion möglich sind.

Der Vorschlag für Klassenfelder befindet sich jetzt in Stufe 3. (Vor einem Monat)

Während die Klassenfelder Stufe 3 erreichten, folgten die privaten Methoden und Zugriffselemente darauf und waren auf Stufe 2, bis sie gestern in Stufe 3 verschoben wurden.

Gibt es ein Update zur Position / zum Fortschritt des TS-Teams bei der Übernahme der #[field] Syntax, jetzt, da es sich seit einiger Zeit in Phase 3 befindet? Ich persönlich mag es wirklich nicht und bevorzuge das vorhandene Schlüsselwort private TS, möchte aber gleichzeitig so nah wie möglich an den Standards sein.

Persönlich mag ich es wirklich nicht und bevorzuge das vorhandene private Schlüsselwort von TS viel

ich auch, es ist so hässlich

aber @mhegazy Ich würde das gerne (versuchen) tun, könnte ich?

Die Analyse sollte nicht schlecht sein (fast ein neuer Modifikator, der fast nur ein Token ist), aber die Typprüfung wird mühsam sein (da wir zwei verschiedene Arten von Privates haben, die irgendwie verglichen werden müssen) und die downlevel emit ist grauenhaft (weil das Downleveling der Privatsphäre der echten Laufzeit eine große Transformation ist - @rbuckton hat Ideen dazu und vielleicht eine Implementierung (ich weiß es nicht genau; er hat viele davon in seiner Gabel)). Wir können Sie technisch nicht davon abhalten, es zu versuchen, aber ich würde es nicht empfehlen, wenn Sie etwas anderes finden, das Sie lieber ausprobieren würden, und ich kann nicht garantieren, dass wir bereit sind, es zu akzeptieren, wenn Sie fertig sind. Außerdem sind private Felder und Methoden zwar fortgeschritten, aber immer noch etwas unvollständig, bis auch private Statik (und möglicherweise Dekoratoren ) Fortschritte macht (angesichts der Art und Weise, wie sie alle interagieren, ist es möglicherweise besser, sie alle auf einmal hinzuzufügen).

Es genügt zu sagen, hier gibt es viel.

@weswigham Ok, ich gebe auf 😂

Hier ist ein Hinweis , dass ich (mit

Update: Unsere laufende Arbeit ist da .

Jawohl. Wir beginnen, die verschiedenen Designs zu untersuchen, die für diese Funktion möglich sind.

Ich mag die # Syntax auch nicht, aber ich verstehe die technischen Gründe für diese Syntax. @mhegazy Was ich wirklich von einem TypeScript-Team tun möchte, überlegen , was TypeScript mit veralteten Implementierungen wie namespace , private tun wird, die verwendet werden können, aber im Allgemeinen sollten? nicht, da es eine bessere Standardmethode gibt, dasselbe oder fast dasselbe zu tun.

Ich möchte auch meine paar Cent über protected hinzufügen. Wenn wir (hoffentlich) eines Tages das Schlüsselwort private entfernen/veralten werden, denke ich, dass es in Ordnung ist, dasselbe mit dem Schlüsselwort protected zu tun. Ich weiß, dass die meisten Leute anderer Meinung sein können, aber ja, zusätzliche Sichtbarkeitsbereiche können manchmal praktisch sein, aber der Gesamtwert ist imho nicht hoch.

@pleerock ,

Das erwarte ich von TypeScript:

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

Ausgeben (mit Ausrichtung auf ESNext):

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

Ausgeben (auf ESNext ausgerichtet, mit neuer Compiler-Option zum Ausgeben von als privat gekennzeichneten Feldern als private ES-Felder):

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

Das sollte abwärtskompatibel sein und es Ihnen gleichzeitig ermöglichen, private ES-Felder mit einer sauberen Syntax zu verwenden.

@glen-84 natürlich wäre es, ich habe über einen langfristigen Plan für veraltete Schlüsselwörter und Syntaxen gesprochen

Wir haben nicht vor, Syntax oder Schlüsselwörter abzuschaffen.

Ich glaube auch nicht, dass wir irgendeine Möglichkeit haben werden, private in # - sie haben ein anderes erwartetes Verhalten; # ist harte Laufzeit-Privatsphäre, während private nur Design-Time-Privatsphäre ist.

@weswigham Das denke ich auch. @ RyanCavanaugh Ja, das war die erwartete Antwort. Aber dennoch würde ich zumindest eine Strategie für neue Benutzer anwenden, um die Verwendung von Namespace / privaten Schlüsselwörtern zu vermeiden, da sie imho mit den neuesten Ecmascript-Vorschlägen veraltet sind

Die Leute finden dies im Allgemeinen anhand des Lesens von Dokumentationen heraus, die wir natürlich aktualisieren. module foo { ist immer noch in der Sprache, wird aber im Grunde nie mehr in freier Wildbahn gesehen, außer in sehr alten Codebasen, die älter sind als namespace foo { .

@RyanCavanaugh gut, das zu hören. Aber ich glaube immer noch, dass neue Leute, die von c# kommen, definitiv versuchen werden, Namespaces zu verwenden (nicht alle, aber einige von ihnen). Ich denke, das Gleiche könnte bei Benutzern aus anderen Sprachen der Fall sein - sie werden privat anstelle von # und dies ist in der Regel massiver als das Beispiel mit Namespaces

Ich glaube auch nicht, dass wir irgendeine Möglichkeit haben werden, private in # zu transpilieren - sie haben ein anderes erwartetes Verhalten; # ist harte Laufzeit-Privatsphäre, während privat nur Design-Zeit-Privatsphäre ist.

D'oh. Ich hatte gehofft, dass wir optional auch private für harte Privatsphäre verwenden könnten, um die ... unglückliche Syntax zu vermeiden.

Wie auch immer, soft-private ist für meine (aktuellen) Anwendungsfälle wahrscheinlich ausreichend.

Ich denke, es wäre großartig, diese Syntaxunterstützung in die kommende 3. Version von TypeScript aufzunehmen, da diese Funktion riesig ist und Version 3 eine gute Gelegenheit bietet, die Leute dazu zu bringen, die neue # Syntax zu verwenden.

EDIT: Verdammt vergessen, dass Version 3 bereits veröffentlicht wurde.

Nur zu Ihrer Information, es gibt in letzter Zeit einige Aufregungen über private Felder/Slots/was auch immer im Repo des TC39-Vorschlags, daher ist es nicht einmal sicher, ob der Vorschlag in seiner aktuellen Form es schaffen wird. Hier sind ein paar relevante Probleme:

Ich bin kein TC39, aber mein persönlicher Vorschlag an alle ist, zuerst zu warten, bis sich die Syntax wieder verfestigt (möglicherweise auf Stufe 4) und dann implementiert.

FWIW Ich würde die Diskussion in tc39/proposal-class-fields#100 nicht als Hinweis auf etwas Bestimmtes interpretieren. # ist auf den ersten Blick nicht schön, aber es wurde keine bevorzugte syntaktische Form vorgeschlagen, und die einzige Syntax, die die Leute zu wünschen scheinen, ist offensichtlich nicht praktikabel. Es muss eine Art Präfix-Sigill geben und alle Versuche, this.someProp privat zu machen, sind zum Scheitern verurteilt.

Mir ist klar, dass das ziemlich abweisend klingt, aber ehrlich gesagt ist das meine Absicht - keiner der Beschwerdeführer in diesen Threads hat sich sinnvoll mit den technischen Kernproblemen beschäftigt, die in bestehenden Threads oder den FAQ angesprochen wurden. Es ist verdammt deprimierend, sich die Threads in diesem Repo durchzulesen und lange korrekte Erklärungen zu sehen, warum ein Siegel benötigt wird, um in den Boden zu fallen.

Wenn das Endspiel darin besteht, dass niemand private Felder verwendet, es sei denn, sie brauchen wirklich harte Laufzeit-Privatsphäre, ist dies wahrscheinlich ein gutes Ergebnis für das Web in Bezug auf Leistung und Fehlersuche.

Ich stimme zu, dass es wahrscheinlich kein ideales Thema ist, um es zu erwähnen, aber das andere,
tc39/proposal-class-fields#106, ist wahrscheinlich viel aussagekräftiger - es gibt
ernsthafte Diskussion darüber, stattdessen unter anderem schwache Karten zu verwenden, weil
Proxy-Interop ist einfach scheiße.


Isiah Wiesen
[email protected]
www.isiahmeadows.com

Am Mo, 30. Juli 2018 um 15:38 Uhr, Ryan Cavanaugh [email protected]
schrieb:

FWIW Ich würde die Diskussion nicht interpretieren in
tc39/proposal-class-fields#100
https://github.com/tc39/proposal-class-fields/issues/100 zu sein
auf etwas Bestimmtes hinweisen. # ist auf den ersten Blick nicht schön, aber
es wurde keine bevorzugte syntaktische Form vorgeschlagen und die einzige Syntax, die
Leute scheinen zu wollen, ist offensichtlich nicht praktikabel. Es muss ein Präfix vorhanden sein
Siegel irgendeiner Art und alle Versuche, dass this.someProp privat ist
sind zum Scheitern verurteilt.

Mir ist klar, dass das ziemlich abweisend klingt, aber das ist ehrlich gesagt meine Absicht -
Keiner der Beschwerdeführer in diesen Threads hat sich sinnvoll mit dem beschäftigt
technische Kernprobleme, die in bestehenden Threads oder den FAQ behandelt werden. Es ist
Es ist verdammt deprimierend, die Threads in diesem Repo durchzulesen und lange zu sehen
korrekte Erklärungen, warum ein Siegel benötigt wird, werden in die
Boden.

Wenn das Endspiel darin besteht, dass niemand private Felder verwendet, es sei denn, sie sind wirklich
brauchen harte Laufzeit-Privatsphäre, das ist wahrscheinlich ein gutes Ergebnis für das Web in
hinsichtlich Leistung und Fehlersuche.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/Microsoft/TypeScript/issues/9950#issuecomment-408984395 ,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AERrBGCphyQUu5lJQW7lgsqALLL3e0_Wks5uL2DLgaJpZM4JVDwV
.

Es gibt einige Diskussionen über die Verwendung von WeakMaps, aber ich sehe nicht, wie dies die Interaktion mit Proxy verbessern würde. Ich würde jedes TC39-Mitglied einladen, das eine andere Vorstellung davon hat, wie private Klassenfunktionen funktionieren sollten, diese dem Komitee zur Rückmeldung vorzulegen; derzeit befindet sich dieser Vorschlag in Stufe 3 und repräsentiert theoretisch die Konsensposition des Ausschusses. Viele Leute haben Kompromisse gemacht, um ein gemeinsames Ziel zu erreichen, diese Funktion zu ermöglichen, auch wenn andere Designs möglich sind.

Ich arbeite daran, eine Diskussion zwischen Frameworks darüber zu organisieren, wie Proxy verwendet wird, um Objektmutationen zu beobachten, und wie dies mit privaten Feldern interagieren sollte. Lassen Sie es mich wissen, wenn Sie an dem Gespräch teilnehmen möchten.

@RyanCavanaugh

FWIW Ich würde die Diskussion in tc39/proposal-class-fields#100 nicht als Hinweis auf etwas # ist auf den ersten Blick nicht schön, aber es wurde keine bevorzugte syntaktische Form vorgeschlagen, und die einzige Syntax, die die Leute zu wünschen scheinen, ist offensichtlich nicht praktikabel. Es muss eine Art Präfix-Sigill geben und alle Versuche, this.someProp privat zu machen, sind zum Scheitern verurteilt.

Später dazu, aber es gibt tatsächlich einen Vorschlag, der die this->var Syntax vorschlägt .

Zugegeben, dieser Vorschlag ist höchstwahrscheinlich tot ("das Komitee war nicht begeistert" ist der einzige Grund, den ich finden konnte). Es wurde jedoch tatsächlich eine alternative Syntax vorgeschlagen, und ich hoffe, dass alle interessierten Parteien diese kennen und kennen.

Ich denke, es wäre schön, eine Compileroption zu haben, um private in eine Art _soft_ private transpilieren zu lassen, die zur Laufzeit erzwungen wird. Ich glaube nicht, dass der Anwendungsfall für die Notwendigkeit von True Hard Private besonders häufig vorkommt, also denke ich, dass die meisten Leute, abgesehen von der Abneigung gegen die # -Syntax, dazu neigen würden, bei private zu bleiben. Aber Kompilierzeit nur privat ist _zu_ weiche IMO. Außerdem würde eine solche Option dazu beitragen, die Anzahl der möglichen Varianten von private zu reduzieren. Wenn Entwickler dies allein implementieren müssen, könnten Sie all dies haben:

class Demo {
  private a

  #b

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

Ich schlage also vor, dass private a bei aktivierter neuer Option zu <strong i="13">@reflect</strong> #a transpiliert, wobei @reflect ein Dekorator ist, der die Reflexion über die Eigenschaft über eine von der Community unterstützte API ermöglicht. Es gab einige sprechen von einer Standard - Dekorateur Bibliothek, so dass die @reflect Dekorateur (oder was auch immer , wir würden es nennen wollen) in Zukunft standardisiert werden könnten; Ich denke, es wäre ein guter Kandidat dafür.

Ich nehme an, der Hauptnachteil meines Vorschlags wäre die Auswirkung auf die Leistung. Wir können hoffen, dass JS eines Tages einige Standard-Dekoratoren haben wird, die nativ implementiert werden, um sie zu optimieren, aber die Realität für die absehbare Zukunft ist, dass <strong i="19">@reflect</strong> #x langsamer sein wird als nur #x . Aber ich schlage dies nur als Option vor, die wahrscheinlich standardmäßig deaktiviert sein sollte (auch aus Gründen der Abwärtskompatibilität).

@MichaelTheriot

Später dazu, aber es gibt tatsächlich einen Vorschlag, der diese->var-Syntax vorschlägt.

Zugegeben, dieser Vorschlag ist höchstwahrscheinlich tot ("das Komitee war nicht begeistert" ist der einzige Grund, den ich finden konnte)

Das Komitee hat viele wohlüberlegte Gründe dafür angegeben, den aktuellen Vorschlag anstelle des Vorschlags der Klasse 1.1 zu unterstützen, zum Beispiel https://github.com/tc39/proposal-class-fields/issues/100#issuecomment -429460917

@mbrowne

Ich habe es vielleicht übersehen. Die Themenseite der Klassen 1.1 ist seit einem halben Jahr inaktiv, und sogar das von Ihnen verlinkte Beispiel wurde einen Monat nach meinem Kommentar geschrieben.

Zu Ihrer Information, ich habe dies in dem Thread

Bearbeiten: Mein Kommentar schlägt nicht vor, dass TypeScript etwas anderes macht. Ich halte es für sinnvoll, Fehlinformationen zu den genannten Themen eines Vorschlags zu korrigieren.

@MichaelTheriot Die Parteien, die über Alternativvorschläge informiert werden müssen, sind nicht die an dieser Konversation beteiligten Parteien. TypeScript wird dem Vorschlag folgen, der auf dem Weg zur Ratifizierung ist. Die Tatsache, dass alternative Syntaxen vorgeschlagen und nicht übernommen wurden, ist meiner Meinung nach für dieses Gespräch nicht wirklich nützlich.

Hey Leute, falls es hilft, möchte ich meine eigene Implementierung von Runtime Protected/Private Members teilen:

Siehe lowclass .

Sehen Sie sich die umfangreichen Testdateien an, die alle Arten von Verwendungen von öffentlichen/geschützten/privaten Laufzeitmitgliedern zeigen. Die Implementierung dauert nicht lange, und einige Funktionen können weggelassen werden, um nur die minimale geschützte/private Funktionalität zu haben.

Anmerkungen:

  • Es verwendet WeakMaps, um den geschützten / privaten Zustand zu speichern.
  • Im Gegensatz zu anderen Implementierungen, die ich gesehen habe, funktioniert es mit asynchronem Code mit Callbacks/Promises/Await, da es nicht auf die synchrone Call-Stack-Ablaufverfolgung angewiesen ist.
  • Es funktioniert mit Gettern/Settern (einschließlich Super Calls) (siehe Tests).
  • Funktioniert mit nativem super oder mit einem Super Helfer für ES5 (siehe Tests).
  • Unterstützt die Methode constructor (siehe Tests).
  • Möglichkeit, eingebaute Klassen zu erweitern (mit Ausnahme von Date, aber ich wollte das untersuchen, obwohl die Leute sagen, dass es nicht möglich ist, aber ich möchte es bestätigen. Siehe Tests, z. B. Arbeiten mit nativen benutzerdefinierten Elementen).
  • Möglichkeit, reguläre native class es zu erweitern (siehe Tests).
  • Wrap native class es, um ihnen geschützte und private Fähigkeiten zu geben (siehe Tests).
  • Schreiben Sie function Klassen im ES5-Stil anstelle von nativen class Klassen (siehe Tests).
  • viel Platz für Leistungsoptimierungen (zB Zwischenspeichern von Super/Protected/Private Helper Calls und Optimierung der Lookup-Algos)

So führen Sie Tests durch:

npm install
npm test

Siehe auch https://github.com/babel/proposals/issues/12 und https://github.com/babel/babel/issues/8421 für Details und Probleme bei der Implementierung von Babel.

Hallo ihr alle,

Bitte implementieren Sie nicht die noch nicht abgeschlossene Spezifikation für private Klassenfelder. Es hat Probleme.

Bitte lies diesen Thread .

Ich möchte jeden, der dies liest, ermutigen, sich einige andere Syntaxideen anzusehen (einfach herumlesen, es gibt noch mehr) und Ihre Meinung äußern.

zB hier ist ein anderer Thread (mit besseren Syntaxideen als das aktuelle # IMHO).


Wenn es eine JavaScript-Community gibt, die Public/Private/Protected bereits weit verbreitet verwendet, dann ist es die TypeScript-Community, die eine große Chance hat, die Zukunft von JS Private/Protected mitzugestalten.

Daher werden private Klassenfelder in V8 v7.2 und Chrome 72 ausgeliefert. Gibt es Pläne, mit der Implementierung des Vorschlags für private Felder zu beginnen?

@ChrisBrownie55 Öffentliche Felder werden versendet. Privat sind es nicht.

@jhpratt das ist mein

Als Referenz: https://v8.dev/blog/v8-release-72#public -class-fields

Es dokumentiert, dass sie ab V8 7.2 öffentliche Klassenfelder versenden, aber es gibt Folgendes in Bezug auf private Felder (Hervorhebung von mir):

Die Unterstützung für private Klassenfelder ist für eine zukünftige V8-Version geplant .

@isiahmeadows Ich

Screenshot of Google Developers page

Abschluss

Felder für öffentliche Klassen werden in V8 v7.2 und Chrome 72 ausgeliefert. Wir planen den Versand von Feldern für private Klassen in Kürze.

Link zum Artikel im Entwicklerblog von Google

Diese Artikel wurden von @mathiasbynens und Andreas Haas geschrieben, die Sie bei Bedarf um Klarstellung bitten können (obwohl ich denke, dass jeder dieser Beiträge ziemlich klar war). cc @gsathya und @joyeecheung , die am Feinschliff der Umsetzung in V8 arbeiten.

Wie auch immer, das TC39-Treffen im Januar 2019 beendete eineinhalb Jahre des Überdenkens von Alternativen zu den Vorschlägen für private Bereiche und Methoden mit einer weiteren Bestätigung des Konsens über die Vorschläge. Ich denke, wir können die aktuelle Version als stabil und bereit für TypeScript betrachten.

Chrome hat gerade private Klassenfelder veröffentlicht 🎉
Sie sind nur in Chrome 74 verfügbar, das derzeit im _canary_-Build veröffentlicht wird.

screenshot of tweet

Ich habe gerade Privatklassenfelder in Chrome 74 ausgeliefert! Probieren Sie es noch heute in Chrome Canary aus!
— Sathya Gunasekaran über Twtiter

Weiß jemand, wo wir hier bei der Auswahl einer bestimmten Implementierung (oder dem Erstellen einer) für private Klassenfelder stehen? Ich sah , dass @trusktr empfohlen lowclass aber ich weiß nicht, ob „_Private Inheritance_“ ein Teil der Spezifikation ist.

Es ist entschieden nicht; private Felder durchlaufen nicht die Prototypkette (da sie dann von anderen Objekten gesehen werden könnten und sie daher nicht privat wären)

Ich würde davon ausgehen, dass private Felder in WeakMaps transpiliert werden (eine WeakMap pro Feld, genauso wie Babel es tut). Es sollte auch eine Option geben, die # Syntax in der endgültigen Ausgabe beizubehalten, für diejenigen, die ausschließlich auf Browser abzielen, die sie unterstützen (dies wird natürlich mit der Zeit relevanter).

Aus Leistungsgründen könnte es auch sinnvoll sein, eine Option in Betracht zu ziehen, die es Entwicklern ermöglicht, die # Syntax für zukünftige Kompatibilität zu verwenden (wenn mehr Browser sie unterstützen), aber tatsächlich mit einem speziellen Präfix in öffentliche Eigenschaften zu transpilieren, z. B. __ts# . WeakMaps sollte einem Benchmarking unterzogen werden, um festzustellen, ob dies tatsächlich erforderlich ist, aber ich vermute, dass der Leistungsunterschied zwischen öffentlichen Eigenschaften und WeakMaps erheblich sein könnte. Wenn eine solche Option hinzugefügt wurde, sollte sie natürlich standardmäßig deaktiviert sein, da Entwickler, die die # Syntax verwenden, normalerweise erwarten würden, dass sie sowohl zur Kompilierzeit als auch zur Laufzeit privat ist. Aber für diejenigen, die die Laufzeitleistung maximieren möchten und in der Zwischenzeit nur mit privater Kompilierungszeit zufrieden sind, könnte dies eine gute Möglichkeit sein, die neue Syntax zu verwenden, ohne möglicherweise eine Leistungseinbuße zu verursachen.

Gibt es Neuigkeiten zum Implementierungsfortschritt? Vielleicht eine PR, die wir zum Testen erstellen und Feedback geben können?

@jhpratt sicher! Wenn Sie sich den Branch in dieser PR ansehen , können Sie privat benannte Instanzfelder testen. Methoden und Accessoren sind in Bearbeitung.

Wir hoffen, diese Arbeit vorgelagert zu haben. Wir können die Änderungen gegen dieses Repo (Microsoft/TypeScript) PRen, sobald diese vorausgesetzte PR zusammengeführt wird: https://github.com/Microsoft/TypeScript/pull/30467.

Feedback ist sehr willkommen.

Ich weiß nicht, ob "Private Vererbung" Teil der Spezifikation ist.

Nebenbei bemerkt, ich plane, diese Funktion in der unteren Klasse zu entfernen, um 100% echte Privatsphäre zu ermöglichen. In der Praxis habe ich es nicht wirklich gebraucht, es war eher ein Experiment.

Übrigens, ich möchte hier gerne posten, falls eine Theorie zur "privaten Vererbung" möglicherweise von Nutzen sein könnte (vielleicht nur interessant oder vielleicht andere Ideen):


bei interesse:

"Private Vererbung" (wie in der aktuellen Version von Lowclass zu sehen) bedeutet, dass eine Unterklasse private Methoden verwenden kann, die von einer Oberklasse geerbt wurden, die Methode jedoch Änderungen _ nur _ auf private Eigenschaften der Instanz _innerhalb des Geltungsbereichs dieser Unterklasse_ anwendet, als ob die Unterklasse hatte diese Methoden in ihrer eigenen Definition als private Methoden definiert, aber die Unterklasse kann private Eigenschaften der Instanz in einem Super- oder Geschwisterklassenbereich nicht ändern.

Im Vergleich dazu _kann_ bei der "geschützten Vererbung" eine Unterklasse die Eigenschaften ihrer eigenen Instanz oder Superklasseninstanz ändern, aber immer noch keine Eigenschaften einer Geschwisterklasse ändern. Bei der geschützten Vererbung modifiziert eine Unterklasse Eigenschaften, die alle Superklassen sehen können (Superklassen lesen/schreiben alle auf dieselben Eigenschaften).

Mit anderen Worten, im Konzept der "privaten Vererbung" hat jede Klasse einen privaten Bereich, und alle geerbten privaten Methoden arbeiten nur im lokalen Klassenbereich, im Gegensatz zu protected, wo geschützte Methoden in einem einzigen Bereich für die gesamte Klassenhierarchie arbeiten.

Ich bin mir nicht sicher, ob das viel Sinn macht, daher sind hier einfache Codebeispiele, um zu erklären, was "private Vererbung" ähnlich wäre, wenn wir es mit den aktuellen privaten Feldfunktionen von ecma Proposal-Class-fields schreiben würden:


Beispielcode ist leichter zu verstehen:

Es gibt keine "private Vererbung" in Vorschlagsklassenfeldern, daher funktioniert Folgendes nicht (und ich stimme zu, dass dies wünschenswert ist, um den wahren Datenschutz zu wahren):

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

In der unteren Klasse wäre "private Vererbung" gleichbedeutend mit dem Schreiben des folgenden Nicht-DRY-Codes, um dasselbe zu emulieren, indem Sie etwas Kopieren/Einfügen in Ihrem Editor verwenden:

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

In beiden Beispielen ist die Variable #foo eine spezifische Variable für jede Klasse. Es gibt zwei #foo Variablen, nicht eine; jeder nur durch Code in derselben Klassendefinition lesbar und beschreibbar.

In Lowclass erlaubt uns die private Vererbung, private Superklassenmethoden wiederzuverwenden , #foo Variablen für jede Klasse.

In lowclass, wenn #someMethod in der Super - Klasse verwendet wird, arbeitet er auf dem #foo der Oberklasse. Wenn #someMethod im Geltungsbereich der Unterklasse verwendet wird, operiert es auf den #foo der Unterklasse, nicht auf den #foo der Oberklasse!

Ich hoffe, das erklärt das Konzept, und selbst wenn es nicht verwendet wird, hoffe ich, dass es interessant oder nützlich sein kann, um Ideen jeglicher Art zu wecken.

Es befindet sich jetzt im stabilen Chrome-Kanal, sodass Entwickler es nativ verwenden können. Ich interessiere mich hauptsächlich für dieses Problem wegen VSCode - beim Schreiben von Vanille .js Javascript markiert VSCode es als Fehler. Gibt es eine Möglichkeit, die Unterstützung für private Klassenfelder in Vanilla JS in VSCode hinzuzufügen, unabhängig von der Debatte, ob sie zu Typescript hinzugefügt werden sollen?

Persönlich glaube ich nicht, dass TS Unterstützung für sie hinzufügen sollte, bevor es Stufe 4 erreicht. TS hat bereits private Kompilierungszeit, die für den Moment gut genug funktioniert. Nachdem es Stufe 4 erreicht hat, würde ich zustimmen, dass es Sinn macht. (Es gab auch gelegentliche Schwankungen in der Diskussion, daher würde ich sie immer noch nicht für die Hauptsendezeit halten.)

Update: Es wird auch in Node 12 Stable unterstützt. Außerdem hat Babel ein Plugin, um diese Syntax umzuwandeln. Entwickler verwenden häufig Funktionen, bevor sie zu Vorschlägen der Stufe 4 werden. Ich würde gerne Unterstützung für diese Syntax in Vanilla JS (non-ts) oder eine Möglichkeit sehen, sie über jsconfig.json aktivieren, damit VSCode bei der Verwendung keinen Fehler anzeigt. Das VSCode-Repository sagt, dass ihre JS-Unterstützung von TypeScript unterstützt wird und verweist auf dieses Problem.

Ich muss sagen, dass es für TypeScript keinen Sinn macht, das Feature überhaupt nicht zu unterstützen, da es in einem großen Browser und Node. Das soll nicht heißen, dass TypeScript jetzt alles komplett festigen und als standardmäßige Funktion freigeben muss.

Ich würde vorschlagen, dass TypeScript private Felder unter einem Flag einführt, das anzeigt, dass diese Funktion experimentell ist und zwischen Stufe 3 und Stufe 4 geändert werden kann.

Vielleicht könnten wir die Syntaxunterstützung zunächst ohne Semantik implementieren?

Vielleicht könnten wir die Syntaxunterstützung zunächst ohne Semantik implementieren?

Für Typprüfung/Intelligenz muss es eine Art Semantik geben, kann aber keine Unterstützung für Downlevel-Transformationen wie BigInt (kann nur mit esnext ).

fwiw, es kann nur in Phase 3 aufgrund von Feedback zur Implementierung geändert werden. Angesichts der Tatsache, dass Chrome es versendet, ist eine Änderung sehr unwahrscheinlich.

@ChrisBrownie55 Ich würde sagen, es macht keinen Sinn, dass diese Funktion noch nicht implementiert ist

Sieht so aus, als ob dies in Arbeit ist:
https://github.com/microsoft/TypeScript/pull/30829
(die anscheinend auf https://github.com/microsoft/TypeScript/pull/30467 wartet)

Richtig, #30829 ist nach dem Rebase bereit zum Zusammenführen, modulo etwas Feature-Gating, das wir vielleicht tun möchten, damit es bei Methoden mit privatem Namen explodiert.

Leute, nur weil ein großer Browser das Feature implementiert hat (um zu sehen, wie es sich anfühlt, damit spielen usw.), bedeutet das nicht, dass jeder dies tun sollte.

Es gab auch gelegentliche Schwankungen in der Diskussion, daher würde ich sie immer noch nicht für die Hauptsendezeit halten

Wie @isiahmeadows erwähnte, ist der Vorschlag für Klassenfelder voller Kontroversen und viele Leute mögen ihn nicht. Hier sind ein paar Probleme, die zeigen, dass die Community die aktuellen privaten Felder nicht mag:

Wenn ich ein Sprachimplementierer wäre, würde ich mir darüber Sorgen machen, und ich würde nicht dafür verantwortlich sein wollen, dass ein sehr unbeliebtes Feature veröffentlicht (in Stein gemeißelt) wird, weil ich beschlossen habe, Tausenden (unwissenden) Entwicklern zu erlauben, ein problematisches zu verwenden Funktion im Produktionscode.

Private Felder ist vielleicht die umstrittenste aller Funktionen, die seit ES6 eingeführt wurden. Ich denke, es wäre klug für einen Sprachimplementierer, die Abneigung in Betracht zu ziehen, bevor er dabei hilft, das Feature in Stein gemeißelt zu haben.

@trusktr Es mag ein umstrittenes Feature sein, aber ob Entwickler es verwenden, sollte dem Entwickler überlassen werden, nicht den Tools. Ein großer Browser hat es nicht zum "Spielen" geliefert, sondern um es für den Einsatz in der Produktion zu liefern. Es wurde auch in Node ausgeliefert, der beliebtesten serverseitigen JS-Laufzeit. Auch hier bin ich weniger besorgt darüber, ob die Syntax es zu TypeScript schafft oder nicht, sondern eher darum, ob die Syntax vom JavaScript-Sprachserver auf VSCode (der von TypeScript unterstützt wird) unterstützt wird.

Es wurde auch in Node versandt

Nur als Nebeneffekt der Chrome-Version, die die JS-Engine von Node beibehält.

Es mag ein umstrittenes Feature sein, aber ob Entwickler es verwenden, sollte dem Entwickler überlassen bleiben, nicht den Tools

Das kann bei Entwicklern wie Ihnen der Fall sein (vielleicht müssen Sie nur ein Produkt veröffentlichen, und Sie werden mit allen Tools arbeiten, die Sie haben, was Sie in dieser Hinsicht tatsächlich tun sollten und was viele angestellte Entwickler tun).

Es gibt auch viele Entwickler, die möglicherweise nichts über die mit Klassenfeldern verbundenen Fußkanonen wissen, während sie nur versuchen, die ihnen zur Verfügung gestellten Werkzeuge zu verwenden.

Und es gibt auch Entwickler, denen die Sprache selbst und die Zukunft des wartbaren Codes am Herzen liegen und die ihn gerne richtig entwickeln würden, bevor bestimmte Fehler zu spät sind, um rückgängig gemacht zu werden.

Das Gute ist, da die neuen privaten Felder die # Syntax verwenden, gibt es noch Raum, um dies mit dem Schlüsselwort private als Alternative zu beheben.

Muss TS wirklich 100% dem Standard folgen? Wir wissen bereits, dass das Komitee mit thisGlobal oder #privateLol gegen die Community vorgeht, also ist es vielleicht an der Zeit zu sagen, dass Google kein Monopol auf JavaScript hat, bevor es zu spät ist?

@TeoTN Private Felder sind keine Sache von Google. Er hat TC39 durchlaufen, wie jeder andere neuere Standard.

Ein paar Punkte zur Verdeutlichung:

  • Wir haben es nicht eilig, ES-Funktionen auszuliefern, die noch nicht vollständig gebacken sind (siehe auch: optionale Verkettung, Null-Koaleszenz, Throw-Ausdrücke, Pipeline-Operator, nameof usw.)
  • Umgekehrt ist die Implementierung ratifizierter und versandter ES-Funktionen nicht optional
  • Viele Leute mögen bestimmte Dinge nicht, so oder so ist es kein Faktor
  • Private Felder befinden sich in TS, wenn wir der Meinung sind, dass die Implementierung für uns sicher ist, ohne dass spätere Designänderungen (oder Widerrufe) ernsthafte Probleme für den Benutzer verursachen

@RyanCavanaugh Danke für die Klarstellung und auch für die tolle Arbeit! Ein kleiner Vorschlag: ES entwickeln sich ständig weiter und es wird an vielen Funktionen gearbeitet. Ich denke, es ist gut, eine Regel zu haben, in welcher Phase - Phase 4? Stufe 3? oder irgendwo dazwischen? - ES-Funktionen sind für die Aufnahme geeignet. Andernfalls könnte sich diese Art von Diskussion in Zukunft für andere Features immer wieder wiederholen.

Von privaten Feldern kann man vernünftigerweise sagen, dass sie vollständig gebacken sind.

@kkimdev Stufe 4 ist so weit wie es geht; es bedeutet, Teil des Standards geworden zu sein.

ES-Funktionen, die nicht vollständig gebacken sind

Neugierig, was sind vollständig gebackene ES-Funktionen? Was bedeutet in diesem Beispiel "voll gebacken"?

Die Implementierung ratifizierter und versandter ES-Funktionen ist nicht optional

Das ist völlig vernünftig, wenn man bedenkt, dass das Ziel von TypeScript, einfach Typen über Vanilla JS zu sein (also Dinge wie namespace in Bezug auf die aktuellen Ziele eine schlechte Wahl waren, und enum ist auch umstritten).

TypeScript hat eine gewisse Macht, der Community bei schwankenden Sprachspezifikationen zu helfen (oder nicht zu helfen), indem es wartet (oder nicht wartet), um ein Feature auszuliefern, bis alle wichtigen Engines das gegebene Feature einstimmig ausgeliefert haben.

Scheint ineffizient zu sein, da TS-Teammitglieder auf TC39 sitzen, also waren sie bereits Teil des Konsenses für ein Feature, das Stufe 3 ist, bevor es überhaupt veröffentlicht wurde - dieses eingeschlossen.

Ich schätze die Designentscheidungen von TypeScript sehr, dass sie bei der Auslieferung konservativ sind; In vielen Fällen ist es sinnvoll, etwas länger zu warten, um Entwicklern die Stabilität zu garantieren. Ich bin sehr zufrieden mit den politischen Entscheidungen in Bezug auf private Bereiche und in häufigem Kontakt mit @DanielRosenwasser darüber. Das TypeScript-Team hat TC39 im Laufe der Jahre viele nützliche Rückmeldungen gegeben, die das Design vieler Funktionen mitgestaltet haben.

Ich denke, der beste Ort, um diese Entscheidungen zum Sprachdesign zu diskutieren, wären die Vorschlagsregister, in TC39-Meetings und in anderen Kontexten, die dieser Arbeit gewidmet sind. Wir haben die Vorschläge für private Felder und Methoden dort ausführlich mit @trusktr besprochen ; Diskussion hier scheint off-topic.

Letztendlich denke ich, dass TC39 der Ort ist, an dem wir weiterhin das Sprachdesign durchführen sollten, und das TypeScript-Repository könnte ein Ort sein, um andere Aspekte zu diskutieren, z stabil genug für den Versand.

Da TypeScript Intellisense die JavaScript-Syntaxhervorhebung in VS Code und die beiden Syntaxhervorhebungsprobleme unterstützt, die ich gefunden habe (Microsoft/vscode#72867 und Microsoft/vscode#39703) in der VS Code-Repository-Weiterleitung hier – wo die Implementierung in TypeScript diskutiert wird – Lassen Sie mich dazu beitragen, indem ich sage, dass es cool wäre, wenn dies kein Fehler in JavaScript-Dateien wäre.

Perfekt gültiges JavaScript wird in VS Code als fehlerhaft markiert, weil ein Compiler für eine andere Sprache gerade entscheidet, ob die Syntax unterstützt wird oder nicht. :-)

Ich habe kein Problem damit, dass sich TypeScript Zeit nimmt, bevor es eine Entscheidung trifft (tatsächlich unterstütze ich es!), aber dies beeinflusst das JavaScript-Syntax-Highlighting in einer Weise, die nicht einfach behoben oder sogar lokal umgangen werden kann (soweit Ich weiß), indem ich die Syntax-Highlighter-Grammatikdatei patche, da keine zu patchen ist (AFAIK).

Obwohl ich nicht zum TypeScript-Team gehöre, arbeiten sie aktiv daran, dies zu implementieren, und ich denke, es gibt derzeit keine großen Zweifel, dass private Felder unterstützt werden. Siehe https://github.com/microsoft/TypeScript/pull/30829.

Ich kann bestätigen, dass daran gearbeitet wird – wir arbeiten mit dem TS-Team zusammen und schließen derzeit eine Rebase ab. Aufgeregt für privat benannte Felder in TS (und, als Erweiterung, Language Server).

Vielen Dank an unsere Mitarbeiter bei Bloomberg für die Implementierung in https://github.com/microsoft/TypeScript/pull/30829!

Sie da. Wenn Sie möchten, dass ich hierfür eine separate Ausgabe erstelle, sagen Sie dies bitte. Ich bin daran interessiert, die Gründe für die Ausgabe des speziellen #private PropertyDeclaration erfahren, das zu diesem Problem geführt hat .

Beispielsweise werden die folgenden Deklarationen generiert:

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

...Angesichts der Eingabe:

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

Ich versuche zuerst zu verstehen, warum es vorhanden sein muss, aber auch, ob es weggelassen werden kann, da ich Tools um die Generierung von Deklarationen herum baue.

Ich versuche zuerst zu verstehen, warum es vorhanden sein muss, aber auch, ob es weggelassen werden kann, da ich Tools um die Generierung von Deklarationen herum baue.

Das Vorhandensein eines privaten macht die Klasse in unserer Analyse nominalistisch, daher ist es wichtig, dies in einer Deklarationsdatei beizubehalten. Sie könnten vielleicht ein Post-Emit-Deklarationstransformator-Tool wie dts-downlevel , um die private Deklaration für ältere TSes in irgendeiner Weise herunterzustufen? (Ich weiß nicht, ob es noch ein Downlevel für #privates gibt)

Um das zu ergänzen, was Wesley gesagt hat: downlevel-dts wandelt #private in den Modifikator private , um die Kompatibilität mit älteren Versionen von TypeScript zu gewährleisten.

Das Vorhandensein eines privaten macht die Klasse in unserer Analyse nominalistisch, daher ist es wichtig, dass dies in einer Deklarationsdatei beibehalten wird

Können Sie näher erläutern, wie es die Klasse nominal macht? 🙂 Bei mehreren privaten Eigenschaften, #foo und #bar , wird immer noch nur eine spezielle Ambient-Deklaration #private zu den Deklarationen hinzugefügt. Es gibt keine Möglichkeit, anhand der Deklarationen zu analysieren, wie die Namen der privaten Eigenschaften waren oder wie viele es waren, da sie alle durch eine einzige #private Eigenschaftsdeklaration ersetzt werden. Ich würde es besser verstehen, wenn die Namen #foo und #bar beibehalten würden. Es ist ein bisschen seltsam, zumal der LanguageService sich beschwert, dass die Eigenschaft #private nie verwendet wird. Für mich sieht es nach einem Bug aus. Aber unter allen Umständen sind private Felder nicht Teil der öffentlichen Eigenschaften des Typs und nicht von außerhalb der Klasse zugänglich, also verstehe ich theoretisch nicht, warum sie Teil der Deklarationen sein müssen. Sollten nicht die gleichen Prinzipien gelten wie für Felder und Methoden, die mit anderen Zugriffsmodifizierern als public annotiert sind, bei denen sie nicht KeyOf der Typ und nicht Teil der Ambient-Deklarationen sind?

Um das zu ergänzen, was Wesley gesagt hat: downlevel-dts wandelt #private in den Modifikator private , um die Kompatibilität mit älteren Versionen von TypeScript zu gewährleisten.

Klingt nach einer guten Lösung. Auf diese Weise wird jedoch die Eigenschaft, die Sie dem Modifikator private geben, nicht Teil der Datei .d.ts , da sie nicht Teil der öffentlichen Eigenschaften des Typs ist. Ich interessiere mich speziell für die Deklarationen, die selbst bei den einfachsten Beispielen Diagnosen für eine nicht verwendete Eigenschaft namens #private generieren.

@wessberg Ich habe den Fehler gemeldet, den Sie bezüglich der unerwünschten Sprachdienstwarnungen bemerkt haben, und kann wahrscheinlich eine Lösung implementieren.

Zu deiner anderen Frage:

Können Sie näher erläutern, wie es die Klasse nominal macht?

Da hat schon mal jemand ein Thema geöffnet.

Ein Grund, in diesen Fällen etwas Nominales zu machen, besteht darin, dass der Implementierer der Klasse eine versteckte Invariante zwischen den privaten Feldern beibehalten kann: Die Strukturierung der Typen würde dieses Ziel zumindest ohne wirklich ausgefallene Typen untergraben, die Dinge wie "Die Liste ist" ausdrücken können immer sortiert" oder "der Durchmesser beträgt 2 * Radius".

Ein weiterer Grund ist, dass Code wie der folgende bei der Typprüfung fehlschlagen sollte, da es keine Möglichkeit gibt, zur Laufzeit "das Richtige zu tun":

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'

Hey Leute, ich bin so begeistert, dass wir #private Syntax haben! Es ist toll!

aber ich muss zugeben, dass ich wirklich fassungslos bin, dass wir keine Abkürzungssyntax haben

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

Ich habe mich gefragt – könnten wir ein Typoskript-Plugin oder eine tsconfig-Option entwickeln, um die Kurzschriftsyntax als experimentelle Funktion zu aktivieren?

Ich sterbe nur für die glatte ergonomische Verbesserung, um so viele unnötige this. -Wiederholungen zu vermeiden – die Nachteile der Abkürzungssyntax, wie im Vorschlag erwähnt, scheinen mir keine großen Sorgen zu machen. also würde ich mich freuen, "experimentalPrivateShorthand": true oder so ähnlich in meinen eigenen Projekten festzulegen

kann das gemacht werden? Vielleicht gibt es einen guten Grund, warum es nicht möglich ist? was wäre der Arbeitsaufwand? Danke schön!

:welle: jagen

@chase-moskal TypeScript implementiert außer Typen nichts über den ECMAScript-Standard hinaus. Der Grund dafür ist eine sich ändernde Semantik, wie private Bereiche und Dekorateure zeigen.

@chase-moskal Der praktischste Weg, um zu vermeiden, dass Sie ständig this eingeben, besteht darin, ehrlich gesagt einfach eine Verknüpfung dafür in Ihrer IDE zuzuweisen (wie zum Beispiel F3). Viele Dinge sind möglich, indem man den TS-Parser oder Babel-Parser verzweigt und Plugins schreibt, aber sie sind alle eine Menge Arbeit und würden Sie aus dem Takt bringen mit offiziellen Tools. Mir ist klar, dass sich Ihre Frage natürlich auf die offizielle Unterstützung bezieht, ich dachte nur, ich würde meine Gedanken teilen.

@jhpratt – Typoskript, das mir geholfen hat, hip zu bleiben. es gab mir Dekorateure und Pfeilfunktionen in alten Zeiten! es war früher konkurrenzfähig mit babel, zumindest mehr als jetzt

Ehrlich gesagt, ich bin einfach ein echter Bauchspeck, dass ich nicht so wunderschöne minimalistische Kurse schreiben kann, wie es meine Babel-nutzenden Kollegen vor mehr als einem Jahr konnten, und Babel hat sogar all den Schnickschnack, nach dem ich mich sehne!


@mbrowne – es ist nicht wirklich die "Schreibbarkeit" des Codes, die so wichtig ist wie die Lesbarkeit , also machen wir uns keine Sorgen über das Zählen von Tastendrücken. mein Punkt ist nur, dass Javascript this Wiederholung zu oft überflüssig ist

Denken Sie jetzt zur besseren Lesbarkeit an Folgendes: Wenn wir die Abkürzung #private Syntax erhalten, würden Sie jedes Mal, wenn Sie jemals this , sofort wissen, dass dies der Fall war, um auf ein öffentliches Mitglied zuzugreifen – ein großer Gewinn für Lesbarkeit!


Wie auch immer, ich habe gerade entdeckt, dass Typoskript private Methoden noch nicht unterstützt

Also braucht das alles nur mehr Arbeit und Zeit, anscheinend von den Bloomberg-Leuten

ohne private Methoden, um die Felder abzugleichen, müssen wir nur warten (denn niemand würde typescript-privates mit Hashtag-privates in derselben Klasse mischen, ohne verrückt zu werden!)

Also modernisiert das Bloomberg-Team hier das Typoskript, und sie waren vor einem Jahr auch an den gleichen Datenschutzfunktionen für Babel beteiligt? Sie tun Gottes Werk und ich bin neugierig warum! mach weiter! Danke schön!

:welle: jagen

Ja, TypeScript hat Ihnen vor Jahren Dekorateure gegeben. Erraten Sie, was? Semantik geändert, große Zeit. Jetzt wird TypeScript die Legacy-API für die nahe Zukunft nicht unterstützen, und es wird massive Schäden verursachen, wenn es beschlossen wird, es zu entfernen. Pfeilfunktionen sind Teil der ECMAScript-Spezifikation, daher ist es völlig irrelevant, diese zu erwähnen.

TypeScript implementiert derzeit keine ECMAScript-Vorschläge, bevor Stufe 3 erreicht ist. Dort müssen Sie die Abkürzung finden, bevor TS interessiert ist.

Ja, TypeScript hat Ihnen vor Jahren Dekorateure gegeben. Erraten Sie, was? Semantik geändert, große Zeit.

Wir leben in einer nicht idealen Welt, und einige Funktionen werden gerade benötigt. Zum Beispiel befindet sich der Vorschlag für Dekorateure noch in Phase 2, aber einige große Projekte (Angular) verwenden sie seit langem aktiv. Ein weiteres Beispiel: ECMAScript spezifiziert keine protected Modifikatoren für Klassenmitglieder, was nützlich ist, um echte Probleme zu lösen.

Jetzt wird TypeScript die Legacy-API für die nahe Zukunft nicht unterstützen, und es wird massive Schäden verursachen, wenn es beschlossen wird, es zu entfernen.

Andere Sprachen führen auch experimentelle Funktionen unter Compiler-Flags ein.

Ich sage nicht, dass TypeScript jeden Vorschlag unter Stufe 1 oder 2 implementieren sollte, aber viele interessante Vorschläge für TS sind einfach hängengeblieben, weil es in ECMAScript keine Äquivalente gibt, zB https://github.com/microsoft/TypeScript/issues/2000

@ikokostya Ich habe Dekorateure als Beispiel für etwas verwendet, bei dem sich die Semantik geändert hat, nachdem TypeScript sie implementiert hat. Sagen Sie wirklich, dass diese Abkürzung "jetzt benötigt" wird? Vertrauen Sie mir, wir können die zusätzlichen fünf Charaktere verwalten. Wenn es Ihnen so wichtig ist, können Sie den Compiler freigeben.

TypeScript war fest entschlossen, vor Stufe 3 nichts zu implementieren, auch nicht unter einer Flagge. Dies wurde bereits in verschiedenen anderen Themen gründlich diskutiert.

Ich sehe nichts außer sich im Kreis zu drehen, daher werde ich nicht weiter antworten, es sei denn, es kommt etwas Bemerkenswertes.

@jhpratt In meinem Punkt geht es nicht um Kurzschrift. Bitte lies meinen Kommentar durch.

Vorschlag über Gabel ist absolut irrelevant.

Nicht alle sind sich einig – und vor allem sind sich nicht alle im TC39-Komitee einig – dass die Kurzschrift Code lesbarer oder intuitiver machen würde. Es gab viele Diskussionen darüber, und die Abkürzungssyntax wurde aufgrund dieser Bedenken in einen separaten Vorschlag verschoben. (Ich habe nicht genug darüber nachgedacht, um mir eine definitive Meinung zu bilden, nur um eine Zusammenfassung zu geben.) Wenn Sie diesen Vorschlag vorantreiben möchten, müssen Sie dem TC39 Feedback geben. Ich bin mir sicher, dass bereits viel Arbeit in die Pflege von TS und die Umsetzung aller Vorschläge, die Stufe 3 erreicht haben, eingebunden ist, daher ist es schwer vorstellbar, dass dies für TS in Betracht gezogen wird, es sei denn, es wird in TC39 weiter vorangetrieben.

aber ich muss zugeben, dass ich wirklich fassungslos bin, dass wir keine Kurzschriftsyntax haben

Diese Abkürzung wäre mit dem Pipeline-Vorschlag nicht vereinbar, der auch # und es wird bereits diskutiert, dass er zu einem Stufe-2-Vorschlag wird. Es macht wirklich keinen Sinn, Vorschläge so früh umzusetzen und dann bahnbrechende Änderungen vorzunehmen. In einem so frühen Stadium wissen Sie noch nicht einmal, welcher Vorschlag gewinnt.

Selbst wenn es sich als kompatibel herausstellt, fallen mir zumindest noch ein paar weitere Anwendungsfälle für einen Präfix-Operator # , die nützlicher sind, als eine Abkürzung für die Eingabe von 5 zusätzlichen Zeichen zu sein.

… vor allem, wenn ein Großteil des Anwendungsfalls für private Felder überhaupt nicht auf this steht (zB static isMe(obj) { try { obj.#x; return true; } catch { return false; } } , um ein Beispiel zu nennen).

@phaux – das sind wirklich gute Informationen über Kurzschrift vs. Pipeline, danke!

@jhpratt

TypeScript war fest entschlossen, vor Stufe 3 nichts zu implementieren, auch nicht unter einer Flagge.

fair genug, aber dann muss darauf hingewiesen werden, dass private Methoden tatsächlich Stufe 3 sind , aber es gibt noch keine Typoskript-Unterstützung – und schau, ich mag den Kurzschriftvorschlag sehr, aber das ist nur ästhetisch – ich bin eigentlich jetzt viel mehr ärgerlich über den Mangel an privaten Methoden und Accessoren im Moment

ich gehe davon aus (bete), dass das Bloomberg-Team hier die Arbeit Gottes am Typoskript fortsetzt, wie sie es vor einem Jahr für Babel getan haben? wenn ja, dann müssen wir wirklich nur geduldig sein und festsitzen :)

Es scheint mir, als ob Typoskript früher viel konkurrenzfähiger mit Babel und Browsern für Ecmascript-Funktionen war, und jetzt ist es eigentlich zu konservativ – wir sind in einer Situation, in der sowohl Babel als auch Chrome ein Jahr zuvor private Felder (unmarkiert) ausgeliefert haben Bloomberg kam um uns zu retten

Die schleichende Divergenz zwischen dem Typoskript- und dem Babel-Feature-Set beunruhigt mich – meine Babel-Freunde haben im letzten Jahr wunderschön glatten Code geschrieben, während ich immer noch hier eine Typoskript-Strafe zahle – sie lachen mich aus!

Ich fand es toll, dass Typoskript experimentelle Flags bot, die es mir ermöglichten, zu entscheiden, was ich in Zukunft für eine Umgestaltung riskieren würde, um mir einige großartige Funktionen zu kaufen – ist es jetzt die Position des Typoskripts, dass es zu gefährlich ist, Entwickler über diese Risiken entscheiden zu lassen, und Ist das Typoskript jetzt mein Kindermädchen?

Es sieht immer mehr so ​​aus, als ob ich großartige Funktionen oder statische Typen auswählen kann – aber ich kann jetzt nicht das Beste aus beiden Welten haben, also wächst in mir eine kognitive Dissonanz

Ich bin wirklich gespannt auf die Dynamik hier – wenn Bloomberg nicht wie ein Ritter in glänzender Rüstung einspringen würde, wie lange hätte es gedauert, bis sich das Typoskript selbst der Herausforderung gestellt hätte? Oder ist das ein Typoskript-Experiment: "Wenn wir diese neuen Funktionen einfach vermeiden.. wie lange dauert es, bis die Community es einfach.. für uns tut?", hah, das ist selbst für mich ziemlich zynisch zu fragen! Oder ist dies vielleicht eine wirklich coole wohlwollende Zusammenarbeit, die neue Wege zur Finanzierung und Unterstützung von Open Source erforscht, und es war nur etwas langsamer als erwartet? oder vielleicht die Philosophie des Typoskripts einfach viel konservativer als früher? Wo befinden wir uns in diesem Spektrum?

für die Implementierung von Funktionen der Stufe 3, fehlt es eher an der Bandbreite oder an der Priorität des Typoskripts?

Entschuldigung, dass ich weiter schimpfe, und hey, ich versuche wirklich nicht, unhöflich zu sein oder ernsthafte Anschuldigungen zu erheben, sondern nur Gedanken aus meiner Außenperspektive zu werfen. Ich bin nur ein Benutzer und bin wirklich neugierig, wie die Leute hier, die besser Bescheid wissen, auf diese Bilder, die ich gemalt habe, reagieren könnten – interessante Diskussion, ich schätze Sie alle!

:welle: jagen

Ich fand es toll, dass Typoskript experimentelle Flags bot, die es mir ermöglichten, zu entscheiden, was ich in Zukunft für eine Umgestaltung riskieren würde, um mir einige großartige Funktionen zu kaufen – ist es jetzt die Position des Typoskripts, dass es zu gefährlich ist, Entwickler über diese Risiken entscheiden zu lassen, und Ist das Typoskript jetzt mein Kindermädchen?

Es geht nicht darum, dich zu bemuttern. Es geht darum, keine Zeit damit verbringen zu wollen, Funktionen zu implementieren, die unweigerlich zu einem Wartungsaufwand werden, wenn sich die Semantik im Angebot ändert. Sie wollen absolut keine Zeit damit verbringen, herauszufinden, wie sie die geänderte Semantik in Einklang bringen können, wenn sie mit der TS-Implementierung in Konflikt geraten. Sie haben Besseres zu tun. Es gibt immer noch einen Berg von typbezogenen Problemen zu lösen, daher ist es sinnvoll, ihre begrenzten Ressourcen dafür aufzuwenden und nicht zu versuchen, die Arbeit von TC39 zusätzlich zur Lösung der Typsystemprobleme zu erledigen.

Was private Methoden und Accessoren angeht: Auch diese sind in V8 nicht implementiert. Klassenmethoden und Instanzfelder sind unterschiedlich, und sie können nicht einfach einen Schalter umlegen, um auch diese zu unterstützen. Sie brauchen Zeit, um sie umzusetzen, und sie haben bereits alle Hände voll mit der Arbeit zu tun, und sie sind ein kleines Team. Darüber hinaus gilt nicht nur, dass der Vorschlag in Stufe 3 sein muss: Sie geben auch ausdrücklich an, dass sie ein hohes Vertrauen in die Semantik des Vorschlags haben möchten, um endgültig zu sein. Obwohl selten, _kann_ sich die Semantik in Stufe 3 ändern. Die Funktion wird ohne triftigen Grund nicht in V8 implementiert. Versteh mich aber nicht falsch; Auch ich würde diesen Vorschlag gerne umgesetzt sehen und kann es kaum erwarten, ihn zu nutzen. Die Umsetzung von Vorschlägen aus früheren Phasen ist jedoch Zeitverschwendung, und die Zeit des TS-Teams wird besser anderweitig verwendet. Es gibt unzählige Vorschläge für Stufe 2, 1 und 0, die ich _heute_ gerne_ verwenden würde, aber ich verstehe, warum ich sie noch nicht haben kann. Geduld, mein Freund.

Sie können auch ganz exklusiv babel verwenden, um Ihr Typoskript zu transpilieren, wenn Sie die Optionen bevorzugen, die Ihnen babel bietet.

@0kku – Sie sagen also, dass es sich nur um ein Bandbreiten-/Kapazitätsproblem handelt und nicht um ein philosophisches – der Rückstand an Fehlern hat jetzt höhere Priorität als die Implementierung von Funktionen der Stufe 3, aber in der früheren Geschichte von Typoskript gab es vielleicht weniger Fehler , und es war daher einfacher, experimentellen Implementierungen Kapazitäten zuzuweisen? Ich kann diese Theorie kaufen, und unsere Antwort sollte sein, zu warten oder einen Beitrag zu leisten

@ljharb – oh das ist jetzt sehr interessant – ist es tatsächlich möglich, Typoskript und Babel so zusammen auszuführen? das Beste aus beiden Welten zu erreichen?

aber ich kann einfach nicht sehen, wie der vscode ts-Sprachdienst noch funktionieren könnte, ohne auf die unbekannte Syntax zu implodieren (wie zum Beispiel private Methoden)? fehlende Intelligenz beißt einen zu großen Teil aus dem Wertversprechen des Typoskripts – wenn die Intelligenz vollständig deaktiviert werden muss, ist die Strategie ein Nicht-Starter

wie könnte man das längerfristig beheben? Ich nehme an, wenn wir spezifische Typoskriptfehler für die Syntax jedes experimentellen Features unterscheiden würden und wenn ein Typoskript-Projekt diese spezifischen Fehler auf der tsconfig-Ebene deaktivieren könnte – dann hätten wir eine Chance, die Tür zu öffnen, um sowohl Babel-Funktionen als auch Typoskript-Funktionen zu nutzen zur gleichen Zeit – Mann, das wäre wirklich cool und würde die gesamte Klasse der Mörder umhauen.. Prost!

:welle: jagen

@ljharb

Du kannst auch ganz exklusiv babel verwenden, um dein Typoskript zu transpilieren

Ich nehme an, Sie könnten einen Typprüfungsprozess einrichten, bei dem Sie nur die privaten Methoden mit Babel transpilieren (aber die Typen für alles andere belassen) und die Typprüfung für diesen Code mit tsc . (Das Build-Skript würde nach der Typprüfung nur Babel verwenden.) Aber Sie müssten viele Syntaxfehler in Ihrer IDE ignorieren - ich denke, das wäre für die meisten Leute ein Deal-Breaker.

@chase-moskal Obwohl das, was @0kku gesagt hat, im Allgemeinen richtig ist, habe ich keinen Grund gesehen, an dieser Stelle keine privaten Methoden in TS zu implementieren. Ich denke, es ist eher so, dass dieser Vorschlag später Stufe 3 erreicht hat als Klassenfelder, und die Implementierer arbeiten noch daran.

Wenn Sie neugierig sind, warum wir nicht gerne auf experimentelle Funktionen springen, sehen Sie sich den Clusterfoxtrot mit enormer Komplexität an , der --useDefineForClassFields . Wir haben sehr, sehr früh Klasseneigenschafts-Intialisierer implementiert, unter der Annahme, dass kein möglicher TC39-Vorschlag mit anderer Semantik auch nur plausibel existieren könnte, und wir haben uns ziemlich geirrt.

Dekorateure tendieren dazu, im selben Boot zu sitzen, und Sie werden überrascht sein, wenn Sie glauben, dass wir die Unterstützung für die alte Semantik vollständig einstellen können. Mehrere große Unternehmen haben große, gut angenommene Frameworks darauf aufgebaut; Es ist völlig unrealistisch, dass wir sagen könnten "Nun, der Flaggenname begann mit experimental also hätten Sie wissen müssen, dass diese Funktion, die in den letzten 5 Jahren unterstützt wurde, eines Tages einfach auf- und verschwinden könnte".

Für diese beiden Funktionen werden wir hier für den Rest unseres Lebens zwei subtil unterschiedliche Codepfade beibehalten, und es ist scheiße, aber das ist der Kompromiss – wir sind sehr entschlossen, TypeScript von Build zu Build beizubehalten Aktualisierungen möglich, ohne das Laufzeitverhalten Ihres Codes zu beeinträchtigen; dieser Kompromiss ist unsichtbar, wenn es zu Ihren Gunsten ist (zB Ihr Programm funktioniert weiter ), aber Sie können die Kehrseite in Bezug auf die eifrige Einführung von Funktionen leichter erkennen.

Aus unserer Sicht können Sie die Laufzeitkompatibilität von Version zu Version nicht ausschließen, genauso wie Sie die Verantwortung für Fahrlässigkeit nicht ausschließen können.

Wir haben uns auch trotz des MASSIVE-Community-Pushbacks mit der frühen Einführung der optionalen Verkettung zurückgehalten – wenn ich einen Cent für jedes Mal hätte, wenn jemand sagte: "Nun, steck es einfach hinter eine Flagge", würde ich dies von einem Boot aus eingeben. Aber es war richtig, denn wir hätten erraten müssen, was (null)?.prop produziert hat, und wir hätten absolut null (nicht undefined ) erraten, und wir' d mit einer anderen andauernden Komplexitätslast leben müssen, um diese herauszufinden. Es gibt hier einen starken kontrafaktischen Vorteil für die Tatsache, dass niemand auf einer Codebasis von 3 Millionen Zeilen sitzt, die mit ?. Nutzung gefüllt sind, wo sie darauf angewiesen sind, dass sie manchmal null , ohne die Möglichkeit zu haben Finden Sie sogar heraus, wie Sie zu den verschiedenen undefined Verhalten

Bloomberg implementierte private Felder, weil sie sich sehr über diese Funktion freuten und begierig waren, zu TypeScript beizutragen. Wenn sie nicht in dieser Situation gewesen wären, hätten wir das Feature wie alles andere selbst implementiert.

Im Allgemeinen würde ich sagen, dass die Zeitleiste von JavaScript sehr, sehr lang ist und dass Sie realistischerweise gutes und ergonomisches JavaScript im Jahr 2020 schreiben können, ohne die Syntax von 2024 zu verwenden, genauso wie Sie gutes und ergonomisches JS im Jahr 2016 schreiben könnten, ohne die Syntax von 2020 zu verwenden. Niemand wird durch die Unfähigkeit blockiert, eine Syntax zu verwenden, die noch nicht einmal eine endgültig entschiedene Semantik hat; es ist nur imaginäre Programmierung an diesem Punkt.

Darüber hinaus ist es nicht einmal 100% sicher, dass der aktuelle Vorschlag für Klassenfelder und alle seine Details es in seiner aktuellen Form bis zur 4. mit einem anderen). Ich würde eine 95-prozentige Sicherheit vermuten, aber im Allgemeinen ist selbst die Umsetzung eines Vorschlags der Stufe 3 nicht ganz ohne Risiko. Die Wahrscheinlichkeit weiterer Änderungen nach Stufe 3 ist jedoch sehr gering, daher halte ich die aktuelle TS-Politik für gut.

Jetzt, da es ein TC39-Mitgliedsunternehmen gibt, das sich bemüht, den [Klassenfelder]-Vorschlag vollständig zu verwerfen und durch einen anderen zu ersetzen

Interessant, vergiss einen Link dazu?


Hier ist eine Idee: Vielleicht könnte das TS-Team etwas Zeit damit verbringen, das Plugin-System zu verbessern, um Plugin-Autoren eine klare API zu geben, die sowohl in die Kompilierzeit als auch in die Intellisense-Zeit des Sprachserver-Protokolls eingehakt. Dies würde es Drittanbietern ermöglichen, beliebige experimentelle Funktionen zu implementieren, einschließlich neuer Syntax, und dennoch über funktionierende Intellisense in IDEs und Texteditoren verfügen.

Als letztes habe ich überprüft, dass ttypescript die einzige Möglichkeit ist, TypeScript-Transformatoren nicht programmgesteuert in tsconfig.json zu konfigurieren, und es hängt nicht an Intellisense von IDEs, so dass Drittanbieter sinnvolle Funktionen entwickeln können, die sich gut integrieren vorhandene Tools wie VS Code sind noch nicht da. Wir möchten unsere schöne VS Code-Erfahrung nicht aufgeben, indem wir zu ttypescript wechseln und uns auf die Terminalausgabe verlassen müssen, während VS Code die Syntax nicht verstehen und Fehler ausgeben kann.

Dann könnte sich TypeScript auf die stabilen Funktionen konzentrieren und Dritte riskante experimentelle Funktionen erstellen oder verwenden (so einfach wie es im Babel-Ökosystem ist).

Interessant, vergiss einen Link dazu?

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

Es gibt einen sehr begrenzten Satz syntaktischer Dinge, die Sie mit einem Babel-Plugin tun können; im Grunde muss der Parser es bereits unterstützen. Der do Ausdruck "plugin" beispielsweise erfordert noch Logik im Kern von Babel selbst: https://github.com/babel/babel/blob/master/packages/babel-parser/src/parser /expression.js#L991 Es unterscheidet sich nicht wirklich von einem Befehlszeilenschalter.

Gibt es ein Problem, das für private Klassenmethoden und Accessoren verfolgt werden kann?

@RyanCavanaugh

Für diese beiden Funktionen werden wir hier für den Rest unseres Lebens zwei subtil unterschiedliche Codepfade beibehalten

Ich denke nicht, dass es so gehen sollte und ich kann mir vorstellen, dass es der ganzen Community schadet. Wenn die Dekorateure Stufe 3 erreichen, ist es meiner Meinung nach angemessen, etwas Zeit für das Upgrade auf die neue Version der Dekoratoren einzuplanen. Möglicherweise wird beides eine Zeit lang unterstützt, kann ein harter Wechsel vorgenommen werden und Legacy-Dekoratoren in TypeScript 4+ fallengelassen werden. Ich kenne den Unterschied zwischen alten und neuen Dekorateuren nicht, weil ich sie nicht benutze (na ja, experimentelle Funktion). Aber ich denke, dass betroffene Projekte an dem Vorschlag arbeiten sollten, wenn der Vorschlag nicht ihren Bedürfnissen entspricht. Es ist besser für alle. TypeScript ist der falsche Ort, um den Krieg um Legacy- und experimentelle Features anzuzetteln.

Ich bereue es, hier gelandet zu sein :/

@RyanCavanaugh

Es gibt einen sehr begrenzten Satz syntaktischer Dinge, die Sie mit einem Babel-Plugin tun können; im Grunde muss der Parser es bereits unterstützen.

Wahr. Aber im Interesse des Vergleichs mit TypeScript können Sie in Babel nur den Parser abspalten und Ihr babel.config.js einrichten, dass es den benutzerdefinierten Parser und alle benutzerdefinierten Syntax-Plugins verwendet, die Sie erstellen. Ja, es ist eine Menge Arbeit (insbesondere zu lernen, wie man zum ersten Mal eine neue Syntax hinzufügt), aber mir ist keine gleichwertige Option für TS bekannt, und natürlich ist es in Babel viel einfacher, Transformations-Plugins basierend auf vorhandener Syntax zu schreiben. Ich bin mir nicht sicher, wie der aktuelle Stand der Anpassungsoptionen in TypeScript ist, aber als ich es vor ein paar Jahren das letzte Mal untersucht habe, sah es so aus, als gäbe es keine andere Möglichkeit, es zu erweitern, als das Ganze zu verzweigen.

Der Hash für Privatpersonen ist IMO hässlich und verwirrend. Es ist schwer durchzusetzen, weil es sonst keine Möglichkeit gibt, sie zu implementieren. Es gibt keinen Build-Schritt wie in TS. Der Effekt ist, dass es Code mit Symbolen für den sehr geringen Gewinn eines „harten Privaten“ verstopft, wobei die Leute denken, es sei die „richtige“ Art, JS zu schreiben, da vielen Leuten beigebracht wird, dass Dinge standardmäßig einfach privat sein sollten.
Es hätte mehr Vorschläge geben sollen, bevor sie in den Standard aufgenommen wurden, insbesondere wenn es diesbezüglich offensichtliche Meinungsverschiedenheiten gab.

@robot56 Dinge sollten standardmäßig nur privat sein. Ihnen wird beigebracht, dass alle Dinge durch Reflexion zugänglich sein sollten, was in der Tat für niemanden gut ist.

@ljharb Ja, das sollten sie. Wenn die Deklaration einer privaten Klasse jedoch darin besteht, Hash-Symbole vor Variablen zu werfen, bedeutet der „richtige“ Weg, eine Klasse in JS zu erstellen, den Leuten beizubringen, einfach Hash-Symbole vor Member-Variablen zu setzen. Nicht nur beim Deklarieren, sondern auch beim Verweisen. Es ist besonders verwirrend, wenn Sie aus anderen Sprachen kommen. Mein erster Gedanke, als ich etwas wie this.#x = this.#something(); und eine Deklaration in einer Klasse sah, war, dass der Hash von der Variablen selbst getrennt war. Ich hätte nie gedacht, dass es sich um einen Modifikator handelt. Der Unterstrich für die Öffentlichkeit, das wirkt auch rückständig. Das ist für TS nicht wirklich relevant, aber nur ein nerviges Gerede, denke ich.

Ja, neue Dinge zu lernen, wenn man in der Vertrautheit zementiert ist, kann eine Anpassung sein. Ich vertraue darauf, dass die JS-Community weiter lernen wird!

(der Hash ist Teil der Variablen selbst, der Name von this.#x ist nicht "x, sondern privat", sondern tatsächlich #x , ein eindeutiger Wert in diesem lexikalischen Geltungsbereich)

Ja, neue Dinge zu lernen, wenn man in der Vertrautheit zementiert ist, kann eine Anpassung sein. Ich vertraue darauf, dass die JS-Community weiter lernen wird!

So wie du es ausdrückst, hört sich das so an, als ob das etwas zu unserer Programmierweisheit beiträgt, während dies nur eine weitere Eigenart von JS ist, die man sich merken muss :D

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen