Eigenschaften der Typescript-Privatklasse

Typescript unterstützt private Eigenschaften für Klassen

Zugriffskontrolle in Typescript-Klassen

Viele Programmiersprachen definieren die Eigenschaften ihrer Klassen standardmäßig als privat. Um sie von außerhalb der Instanz zugänglich zu machen, müssen Sie die entsprechenden Eigenschaften in der Regel mit dem Schlüsselwort „public“ markieren.

Das gleiche Schlüsselwort ist auch in Typescript-Klassen verfügbar, hat aber keine große Auswirkung, da Eigenschaften in Typescript-Klassen standardmäßig öffentlich sind. Diese Einschränkung wird von Javascript geerbt, das keine privaten Eigenschaften in Klassen unterstützt. Nun, bis vor kurzem.

Private Felder in Javascript?

Ja und nein. Derzeit befindet sich ein Arbeitsentwurf für eine Spezifikation, die private Eigenschaften in Javascript-Klassen definiert, in Stufe 3, was darauf hindeutet, dass eine endgültige Definition plausibel, aber noch nicht sicher ist.

Die vorgeschlagenen Änderungen in der Spezifikation sind wirklich einfach und ändern die Syntax nur geringfügig. Um eine Eigenschaft als privat zu kennzeichnen, stellen Sie ihr einfach einen Hashtag voran. Das ist es!

class User {
  // A prop marked as private.
  #id;
  age;
  
  constructor(age){
    this.age = age;
    // Valid assignment, as we're 
    // within the class.
    this.#id = Math.floor(Math.random() * 1000);
  }
}

// ... Later in the code ...

const user = new User(42);
// Error! Won't work as it's private.
user.#id = 123;

Private Felder in Maschinenschrift!

Dieselbe Syntax gilt für private Eigenschaften in Typescript. Seit Version 3.8 können Sie mit dieser Funktion den Zugriff auf Eigenschaften und Funktionen für Instanzen sowie statische Felder besser steuern. Die Syntax ist die gleiche wie im Javascript-Beispiel.

Einen Moment bitte, private statische Felder?

Ja, Sie haben richtig gelesen: Sowohl statische Variablen als auch Funktionen können privat sein, was bedeutet, dass sie nur innerhalb der Member der Klasse aufgerufen werden können. Diese Funktion wurde mit Typescript Version 4.3 hinzugefügt, zusammen mit weiteren Änderungen unter der Haube. Laut der Dokumentation für Version 4.3 sind private Klassenmitglieder jetzt zur Laufzeit wirklich privat, was darauf hindeutet, dass diese Funktion vollständig ausgereift ist.

Bitte beachten Sie, dass Typescript zwei verschiedene Varianten von "private" für Klassen unterstützt. Die allgemein bekannte ist mit dem Schlüsselwort "private", das die markierten Felder auch von abgeleiteten Klassen unzugänglich hält.

Die andere Funktion, die ich hier zeige und die neu ist, ist die Verwendung sogenannter "privater Namen". Sie haben dieselbe Syntax wie für Javascript, da ihre Spezifikation ursprünglich von JS definiert wurde. In Typescript steuern sie den Zugriff zur Laufzeit.

/**
 * A class that uses already known
 * private props.
 */
class CommonUser {
  // Common 'private' prop in TS.
  private id: number;
  age: number;
  
  constructor(age: number){
    this.age = age;
    this.id = Math.floor(Math.random() * 1000);
  }
}

/**
 * Using the new sytanx for private class names.
 */
class SpecialUser {
  #id: number;
  age: number;
  
  constructor(age: number){
    this.age = age;
    // Valid, we're inside the class.
    this.#id = SpecialUser.#generateId();
  }
  
  static #generateId(){
    return Math.floor(Math.random() * 1000);
  }
  
  #stringifyId(){
    return this.#id.toString();
  }
}

// ... Later in the code ...

// Invalid, call is outside of class 'SpecialUser'.
SpecialUser.#generateId();

const user = new SpecialUser(42);
// And that won't work as well.
user.#stringifyId();

Letzte Worte zum letzten Kapitel

Dieser Artikel ist nicht sehr lang, hebt jedoch eine großartige Funktion hervor, die Typescript jetzt bietet, sowie einen allgemeineren Vorteil von Typescript selbst. Für Javascript sind private Eigenschaften noch ein Entwurf (wenn auch in einem sehr späten Stadium), aber für Typescript sind sie bereits implementiert und ausgeliefert, was die Geschwindigkeit zeigt, mit der sich diese Sprache entwickelt!