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
}
}
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.
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();
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;
})();
}
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;
})();
}
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.
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]();
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:
Env
Pour annuler ces problèmes, redéfinissez _Initialize à la fin de _Initialize
:
this._Initialize = ()=>{}
Vous recherchez un objet :):
const dataManagement: { subjects: string[] } = {
subjects: []
};
export { dataManagement };
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.