Website-Suche

JavaScript - TypeScript statische Klassen


Ich wollte von traditionellem JS zu TypeScript wechseln, weil mir die C#-ähnliche Syntax gefällt. Mein Problem ist, dass ich nicht herausfinden kann, wie man statische Klassen in TypeScript deklariert.

In C# verwende ich oft statische Klassen, um Variablen und Methoden zu organisieren, indem ich sie in einer benannten Klasse zusammenfüge, ohne ein Objekt instanziieren zu müssen. In reinem JS habe ich dies früher mit einem einfachen JS-Objekt gemacht:

var myStaticClass = {
    property: 10,
    method: function(){}
}

In TypeScript würde ich lieber meinen C-Sharp-Ansatz wählen, aber es scheint, dass statische Klassen in TS nicht existieren. Was ist die geeignete Lösung für dieses Problem?

Antwort #1

Abstrakte Klassen sind seit TypeScript 1.6 ein erstklassiger Bestandteil von TypeScript. Sie können eine abstrakte Klasse nicht instanziieren.

Hier ist ein Beispiel:

export abstract class MyClass {         
    public static myProp = "Hello";

    public static doSomething(): string {
      return "World";
    }
}

const okay = MyClass.doSomething();

//const errors = new MyClass(); // Error

Antwort #2

TypeScript ist nicht C#, daher sollte man nicht unbedingt dieselben Konzepte von C# in TypeScript erwarten. Die Frage ist, warum wollen Sie statische Klassen?

In C# ist eine statische Klasse einfach eine Klasse, die nicht unterklassenfähig ist und nur statische Methoden enthalten darf. C# erlaubt es nicht, Funktionen außerhalb von Klassen zu definieren. In TypeScript ist dies jedoch möglich.

Wenn Sie nach einer Möglichkeit suchen, Ihre Funktionen/Methoden in einem Namespace (d.h. nicht global) unterzubringen, könnten Sie in Erwägung ziehen, die Module von TypeScript zu verwenden, z.B.

module M {
    var s = "hello";
    export function f() {
        return s;
    }
}

Damit Sie M.f() von außen aufrufen können, aber nicht s, und Sie das Modul nicht erweitern können.

Siehe die TypeScript-Spezifikation für weitere Details.

Antwort #3

Das Definieren statischer Eigenschaften und Methoden einer Klasse wird in 8.2.1 der Typescript-Sprachspezifikation beschrieben:

class Point { 
  constructor(public x: number, public y: number) { 
    throw new Error('cannot instantiate using a static class');
  } 
  public distance(p: Point) { 
    var dx = this.x - p.x; 
    var dy = this.y - p.y; 
    return Math.sqrt(dx * dx + dy * dy); 
  } 
  static origin = new Point(0, 0); 
  static distance(p1: Point, p2: Point) { 
    return p1.distance(p2); 
  } 
}

wobei Point.distance() eine statische (oder „Klassen-“) Methode ist.

AKTUALISIERUNG: Der obige Link wurde auf die aktuellste verfügbare Version der TypeScript-Spezifikation aktualisiert, aber bitte beachten Sie, dass es gemäß https://github.com/Microsoft/TypeScript/issues/15711 keine derzeitige autoritative Spezifikation für TypeScript gibt und auch nicht erwartet wird, dass eine solche existiert.

Antwort #4

Diese Frage ist ziemlich alt, aber ich wollte eine Antwort hinterlassen, die die aktuelle Version der Sprache nutzt. Leider existieren statische Klassen in TypeScript immer noch nicht, aber man kann eine Klasse schreiben, die sich ähnlich verhält, mit nur geringem Mehraufwand, indem man einen privaten Konstruktor verwendet, der die Instanziierung von Klassen von außen verhindert.

class MyStaticClass {
    public static readonly property: number = 42;
    public static myMethod(): void { /* ... */ }
    private constructor() { /* noop */ }
}

Dieses Snippet ermöglicht es Ihnen, "statische" Klassen ähnlich dem C#-Gegenstück zu verwenden, mit dem einzigen Nachteil, dass es immer noch möglich ist, sie von innen zu instanziieren. Glücklicherweise können Sie jedoch keine Klassen mit privaten Konstruktoren erweitern.

Antwort #5

Ich hatte heute (31.07.2018) denselben Anwendungsfall und habe dies als Workaround gefunden. Es basiert auf meinen Recherchen und hat für mich funktioniert. Erwartung - Folgendes in TypeScript zu erreichen:

var myStaticClass = {
    property: 10,
    method: function(){} 
}

Ich habe das gemacht:

//MyStaticMembers.ts
namespace MyStaticMembers {
        class MyStaticClass {
           static property: number = 10;
           static myMethod() {...}
        }
        export function Property(): number {
           return MyStaticClass.property;
        }
        export function Method(): void {
           return MyStaticClass.myMethod();
        }
     }

Daher werden wir es wie folgt konsumieren:

//app.ts
/// <reference path="MyStaticMembers.ts" />
    console.log(MyStaticMembers.Property);
    MyStaticMembers.Method();

Das hat bei mir funktioniert. Wenn jemand andere bessere Vorschläge hat, lasst es uns bitte alle hören!!! Danke...

Verwandte Artikel