So strukturieren Sie die Utility-Klasse


73

Ich habe mehrere Dienstprogrammfunktionen. Was ist der beste Weg, um diese zu verpacken und dann zu importieren?

Das versuche ich zu tun:

import * as util from './util'

export class myClass{
     constructor()
     {
           util.doSomething("test");
     }
}

Dann in der Klasse:

export class Util{
    doSomething(val: string){ return val;}

    doSomethingElse(val: string{ return val;}
}

Die Fehlermeldung, die ich von VS erhalte, lautet:

Property doSomething does not exist on type util.

Antworten:


127

Wenn Sie eine Datei erstellen, utils.tsdie enthält

export default class Utils {
    static doSomething(val: string) { return val; }
    static doSomethingElse(val: string) { return val; }
}

Dann können Sie Ihren Client-Code folgendermaßen vereinfachen:

import Utils from './utils'

export class MyClass {
     constructor()
     {
         Utils.doSomething("test");
     }
}

4
So mache ich es jetzt lieber.
Greg Gum

Müssen die Methoden statisch sein? Kann eine Instanz der Utils-Klasse nicht erstellt und verwendet werden?
user728630

7
@GregGum Es ist eine schlechte Idee, Ihre zustandslosen Funktionen nur zum Teufel in eine Klasse zu packen, da dadurch Techniken zur Moduloptimierung wie das Baumschütteln gebrochen werden. Sie sollten alles so nah wie möglich an die oberste Ebene des Moduls exportieren.
Asad Saeeduddin

14
Aufgrund der Kommentare zu meiner Antwort scheint es, dass ich dies in meinem vorherigen Kommentar nicht ausreichend geklärt habe: Es class Utilsist eine schlechte Idee, vollständig zustandslose Funktionen als statische Mitglieder von a zu verpacken , wie in dieser Antwort gezeigt . Die Moduloptimierung wird ohne jeglichen Nutzen für Sie unterbrochen. Wenn Ihre Mitglieder wie doSomethingund doSomethingElsevöllig staatenlos sind und nicht auf private Mitglieder einer Klasse verweisen, sollten sie überhaupt nicht in einer Klasse sein. Sie sollten sie direkt mit exportieren export function doSomething ....
Asad Saeeduddin

1
Mit @GregGum einverstanden, wurde dasselbe in Typ-Skript-Dokumenten übermittelt. Schauen Sie mal
rein

42

Hier gibt es ein paar Probleme:

  1. Sie instanziieren nichts und doSomethingsind eine Instanzmethode
  2. Wenn Sie dies tun import * as util, wird utildas Modul dargestellt, kein Objekt darin.

Wenn Sie möchten Util, sollten Sie einfach Folgendes importieren:

import { Util } from './util'

Als nächstes sollten Sie instanziieren Util, bevor Sie die Methode darauf aufrufen:

var u = new Util();
u.doSomething("test");

Hier ist Ihr Code gepatcht:

import { Util } from './util'

export class MyClass{
     constructor()
     {
         var u = new Util();
         u.doSomething("test");
     }
}

Alles in allem scheint die Art und Weise, wie Sie Ihre Utensilien verwenden, etwas Seltsames zu sein. Dies ist eine ganz persönliche Meinung, aber ich würde keine Methoden aufrufen, die in einem Konstruktor "etwas tun", dh Nebenwirkungen verursachen.

Außerdem sehen die Methoden in Utilnicht wirklich so aus, als müssten sie in dieser Klasse sein, da die Klasse keinen Status hat, von dem sie abhängen. Sie können jederzeit reguläre Funktionen aus einem Modul exportieren. Wenn Sie Ihr Utils-Modul folgendermaßen geschrieben haben:

export function doSomething(val: string) { return val; }

export function doSomethingElse(val: string) { return val; }

Sie würden Ihre Funktionen direkt exportieren und den Instanziierungsaufwand umgehen, und tatsächlich würde Ihr ursprünglicher Code so wie er ist korrekt funktionieren.


1
Vielen Dank. Ja, export function...das habe ich versucht.
Greg Gum

2
Util-Module sollten nicht als Instanz mit dem newSchlüsselwort instanziiert werden . Wenn Sie Standardkonventionen befolgen und die Erstellung von Ausführungskontexten reduzieren möchten, sollten die Util-Klassenmethoden statische Methoden sein, auf die überUtil.doSomething()
Drenai

2
@ Ryan Du liegst falsch. Wenn die zu exportierende Funktionalität von einem bestimmten Status abhängt, sollten Sie sie als instanziierbare Klasse exportieren. Wenn es wie in diesem Fall zustandslos ist, sollten Sie es als unabhängige Exporte der obersten Ebene exportieren . Wenn Sie sie nur ohne Grund in eine statische Klasse packen, brechen Sie das Baumschütteln, ohne dass Sie davon profitieren.
Asad Saeeduddin

Die ursprüngliche Frage beschreibt ein Util, das von keinem Status abhängt. Sie sind gerade statische Funktionen. Wollen Sie damit sagen, dass das Schütteln von Bäumen brechen wird, wenn Sie das Util nicht instanziieren?
Drenai

2
Nein, ich sage, Baumschütteln wird brechen, wenn Sie es class Utilüberhaupt tun . Da die Mitglieder staatenlos sind (was ich in meiner Antwort und an dieser Stelle in zwei verschiedenen Kommentaren erwähnt habe), sollten Sie überhaupt keine Klasse haben . Sie sollten die Mitglieder direkt exportieren, um das Baumschütteln auszunutzen.
Asad Saeeduddin

5

Alternativer Weg:

  1. Exportieren Sie Konstanten in Ihre utils.tsDatei:

    export const doSomething = (val: string): any => {
      return val;
    };
    
    export const doSomethingElse = (val: string): any => {
      return val;
    };
    
  2. Importieren und verwenden Sie diese Methoden in der Hauptdatei *.ts:

    import { doSomething, doSomethingElse } from './util';
    ...
    let value1 = doSomething('abc');
    let value2 = doSomethingElse ('efg');
    

Dies funktionierte am besten für meine Situation. Ich konnte import * as Util from './util';und benutze Funktionen als Util.doSomething('abc');.
Kentaro

1

Oder Sie könnten exportieren ist als Objektliteral:

export const Util = {
    doSomething(val: string){ return val;},
    doSomethingElse(val: string{ return val;}
}

Dies ist wahrscheinlich der beste Weg, dies zu tun. Normalerweise würde ich die Funktionen wie constoben in der Datei erstellen und dannexport const Util { doSomething, doSomethingElse }
Drenai

1

Sie können auch eine util.tsKlasse erstellen , die eine zu exportierende Funktion hat

export const formatDateOfBirth = 
(dob: string) : string => `${dob.substring(0, 4)}-${dob.substring(4, 6)}-${dob.substring(6, 8)}`;

Jetzt können Sie die Methode importieren , wie unten, gemeinsame Ordnerstruktur ist src> app> shared, ich rufe diesen Import innen src> app>shelf > shelf.component.tsDatei

import { formatDateOfBirth } from '../shared/utils/util';
public getFormattedDate(dob: string):string{
  return formatDateOfBirth(dob);
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.