web-dev-qa-db-fra.com

Dactylographe constructeur statique

J'ai lu sur un constructeur statique dans TypeScript et l'ai essayé moi-même mais cela ne fonctionne pas. Je veux initialiser une variable statique par cela - La méthode ne doit être appelée qu'une seule fois.

Erreur: le modificateur 'statique' ne peut pas apparaître sur une déclaration de constructeur.

Code:

export class DataManagement {
private static subjects: string[];

static constructor() {
    DataManagement.subjects = [];
    //some more code here
}

}

10
TheProgrammer

Alors que d'autres langages comme C # ont des constructeurs statiques, TypeScript (et JavaScript) n'ont pas cette fonctionnalité. Cela dit, vous pouvez toujours définir statiquement une fonction que vous invoquez vous-même. Tout d'abord, laissez-moi vous expliquer dans quels cas vous pourriez avoir besoin d'un constructeur statique avant de passer en revue les options dont vous disposez.

Quand utiliser un constructeur statique

Un constructeur statique est utile dans les cas où vous devez calculer la valeur d'un attribut statique. Si vous souhaitez simplement définir un attribut (sur une valeur connue), vous n'avez pas besoin d'un constructeur statique. Cela peut être fait comme ceci:

class Example {
    public static info = 123;
    // ...
}

Dans le cas où vous devez calculer la valeur, vous avez trois façons de "simuler" un constructeur statique. Je passe en revue les options ci-dessous et définit l'attribut statique "info" dans chaque échantillon.

Option 1: appeler une fonction d'initialisation après la déclaration de la classe

Dans le code ci-dessous, la fonction _initialize est défini statiquement dans la classe et appelé immédiatement après la déclaration de la classe. Dans la fonction, this fait référence à la classe, ce qui signifie que le mot clé peut être utilisé pour définir toutes les valeurs statiques (comme info dans l'exemple ci-dessous). Notez qu'il n'est pas possible de rendre la fonction privée, car elle est invoquée de l'extérieur.

class Example {
    public static info: number;

    public static _initialize() {
        // ...
        this.info = 123;
    }
}
Example._initialize();

Option 2: appeler directement la fonction à l'intérieur de la classe

La deuxième option consiste à utiliser une fonction, qui est directement appelée après sa création dans la classe. La fonction seulement regarde comme sa partie de la classe, mais n'a aucun rapport avec la classe elle-même (sauf être définie à l'intérieur de celle-ci), ce qui signifie que vous ne pouvez pas utiliser this à l'intérieur de la fonction.

class Example {
    static info: number;

    private static _initialize = (() => {
        // "this" cannot be used here
        Example.info = 1234;
    })();
}

Alternative: calculer un seul attribut

Basé sur la même idée que l'option 2, vous pouvez calculer un seul attribut en renvoyant la valeur. Cela peut être utile dans les cas où vous ne souhaitez calculer qu'un seul attribut de la classe.

class Example {
    public static info = (() => {
        // ... calculate the value and return it
        return 123;
    })();
}

Quoi utiliser

Si vous souhaitez uniquement calculer un seul attribut statique, vous pouvez utiliser la dernière approche ( alternative). Si vous avez besoin de faire des calculs plus complexes ou si vous souhaitez définir plus d'attributs, je recommande d'utiliser l'option 1 si cela ne vous dérange pas que la fonction soit publique. Sinon, allez avec l'option 2.

Notez qu'il existe un problème dans le référentiel TypeScript, qui contient d'autres discussions concernant les options 1 et 2.

3
Thomas Dondorf

Symbol() peut être utilisé pour cela, proprement avec un accès public restreint.

const STATIC_INIT = Symbol(); // gives you a unique identifier

class MyClass {
  public static[STATIC_INIT] = () => {
    // Your static init code here
  }
}

// Call the init once
MyClass[STATIC_INIT]();
1
Santhos

Vous pouvez simuler un constructeur statique à l'aide de code statique dans votre fichier .ts.

Disons que vous avez une classe qui sert un seul but à analyser les paramètres et à les fusionner avec quelques valeurs par défaut.

Ajoutez simplement un appel après votre déclaration de classe.

Voici un exemple:

export class Env {
    private static _args: {}
    static get args() {
        return this._args;
    }

    static _Initialize() {
        // load settings from Environment
        process.argv.forEach(s => console.log(s))
        this._args =  Object.assign({}, defaults, this.parseCmdLine())
    }
}
Env._Initialize();

Exemple d'application TS: https://github.com/v-andrew/ts-template

Il fonctionne exactement comme un constructeur statique avec qui met en garde:

  • Il pourrait être appelé plusieurs fois
  • Il pourrait être appelé par d'autres utilisateurs de Env

Pour annuler ces problèmes, redéfinissez _Initialize à la fin de _Initialize:

        this._Initialize = ()=>{}
1
v-andrew

Vous recherchez un objet :):

 const dataManagement: { subjects: string[] } = {
   subjects: []
 };

 export { dataManagement };
0
Jonas Wilms

Donc, l'utilisation d'un constructeur statique est un peu impropre. vous n'essayez pas de rendre la méthode constructeur statique, mais essayez de créer une méthode d'instanciation statique. Il peut être nommé comme vous le souhaitez. J'ai utilisé initialize, personnellement.

Vous pouvez avoir votre méthode constructeur essentiellement vide

constructor() {}

Et puis avoir une méthode d'initialisation statique

static initialize(): <type-to-use> { //initialization logic };

généralement, dans la méthode initialize, vous souhaitez invoquer le constructeur avec le mot-clé new, puis par défaut vos propriétés.

0
dweill