javascript - TypeScript statické triedy


Chcel som prejsť na TypeScript z tradičného JS, pretože sa mi páči syntax podobná C#. Môj problém je, že nemôžem zistiť, ako deklarovať statické triedy v TypeScripte.

V C# často používam statické triedy na organizovanie premenných a metód, umiestňujúc ich spolu do pomenovanej triedy, bez potreby vytvárania inštancie objektu. Vo vanilkovom JS som to robil s jednoduchým JS objektom:

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

V TypeScripte by som radšej použil svoj C-sharpy prístup, ale zdá sa, že statické triedy v TS neexistujú. Aké je vhodné riešenie tohto problému?

Odpoveď č. 1

Abstraktné triedy sú plnohodnotným prvkom TypeScriptu od verzie TypeScript 1.6. Abstraktnú triedu nemôžete inštancovať.

Tu je príklad:

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

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

const okay = MyClass.doSomething();

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

Odpoveď č. 2

TypeScript nie je C#, takže by ste nemali očakávať rovnaké koncepty ako v C#. Otázkou je, prečo chcete statické triedy?

V jazyku C# je statická trieda jednoducho trieda, ktorú nie je možné podtriedy a musí obsahovať iba statické metódy. C# neumožňuje definovať funkcie mimo tried. V TypeScripte je to však možné.

Ak hľadáte spôsob, ako umiestniť svoje funkcie/metódy do menného priestoru (t.j. nie globálne), môžete zvážiť použitie modulov TypeScript, napr.

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

Aby ste mohli pristupovať k M.f() zvonku, ale nie k s, a nemôžete rozširovať modul.

Ďalšie podrobnosti nájdete v špecifikácii TypeScriptu.

Odpoveď č. 3

Definovanie statických vlastností a metód triedy je popísané v 8.2.1 Špecifikácie jazyka TypeScript:

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

kde Point.distance() je statická (alebo „triedna“) metóda.

AKTUALIZÁCIA: Odkaz vyššie bol aktualizovaný na najnovšiu dostupnú verziu špecifikácie TypeScriptu, ale prosím, všimnite si, že podľa https://github.com/Microsoft/TypeScript/issues/15711 neexistuje aktuálna autoritatívna špecifikácia TypeScriptu a neočakáva sa, že by nejaká bola.

Odpoveď č. 4

Táto otázka je dosť stará, no chcel som zanechať odpoveď, ktorá využíva aktuálnu verziu jazyka. Bohužiaľ statické triedy stále v TypeScripte neexistujú, avšak môžete napísať triedu, ktorá sa správa podobne s iba malým režijným nákladom, pričom použijete súkromný konštruktor, ktorý zabraňuje vytváraniu inštancií tried zvonku.

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

Tento úryvok vám umožní používať „statické“ triedy podobne ako v C#, s jedinou nevýhodou, že je stále možné ich inštancovať zvnútra. Našťastie však nemôžete rozširovať triedy s privátnymi konštruktormi.

Odpoveď č. 5

Dnes (31/07/2018) som mal rovnaký prípad použitia a našiel som toto riešenie. Je založené na mojom výskume a fungovalo to pre mňa. Očakávanie - Dosiahnuť nasledujúce v TypeScripte:

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

Urobil som toto:

//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();
        }
     }

Preto ho spotrebujeme takto:

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

Toto mi fungovalo. Ak niekto má iné lepšie návrhy, prosím, podeľte sa s nami všetkými!!! Ďakujem...

Súvisiace články