node.js - Typescript - Odefinierat fel för statiska variabler


Jag har denna Node API-app byggd med Express och Typescript. Innan jag startar servern initialiserar jag den statiska variabeln i Configuration-klassen med den nödvändiga konfigurationen. Men när jag använder denna statiska variabel i en separat Typescript-klass i hela applikationen får jag ständigt detta undefined-fel.

Finns det något som jag missar här?

server.ts

// Initialize Config
Configuration.initAppConfig();

server.start()

app.config.ts

import config from 'config';
const packageInfo = require('../../package.json');

// other imports 

export class Configuration {

   static appConfig: IAppConfig;

   static initAppConfig() {

       Configuration.appConfig = <IAppConfig>{
           appName: packageInfo.name,
           db: <IDbConfig>config.get("db"),
           server: <IServerConfig>config.get("server")
       }
       //prevent it from getting reassigned
       Object.freeze(this.appConfig);
   }
}

db.config.ts

import { Configuration } from './app.config';
export class DBConfig{

private static logger = LoggerFactory.getLogger(Configuration.appConfig.appName);

// other stuffs
}

Fel

    private static logger = LoggerFactory.getLogger(Configuration.appConfig.appName);
                                                                            ^
    TypeError: Cannot read property 'appName' of undefined

PS: Det fungerar om jag tar bort static från logger. Någon anledning till varför detta händer? Jag slår bokstavligen mitt huvud mot väggen. :|

//works    
private logger: Logger = LoggerFactory.getLogger(Configuration.appConfig.appName);

//Not working - appName of undefined error
private static logger: Logger = LoggerFactory.getLogger(Configuration.appConfig.appName);

Svar #1

Den största skillnaden mellan versionen som fungerar (utan static) och versionen som inte fungerar (med static) är tidpunkten för när medlemmen initialiseras.

När medlemmen inte är statisk, initieras den endast när någon kod (som inte visas här) skapar en instans av den innehållande klassen (DBConfig). Vid den tidpunkten har Configuration.appConfig redan initierats.

När medlemmen är statisk, initieras den mycket tidigare, vid en tidpunkt när Configuration.appConfig ännu inte är initierad.

Ett sätt att övervinna detta är att säkerställa att Configuration.appConfig initialiseras först, till exempel genom att använda ett synkront anrop (eller några andra lösningar, beroende på strukturen i dina kodsegment som inte visas här).

Svar #2

När det gäller instans/statisk, tillhör instansmetoder instansen av en klass (objekt skapade med nyckelordet "new") och statiska metoder utvidgar klassen, vilket betyder att de tillhör själva klassen och är tillgängliga för alla instanser (objekt) av klassen.

Så, om du försöker anropa instansmetoden från en statisk metod betyder det att du försöker få åtkomst till instansmetoden hos en redan existerande instans inuti den statiska metoden. Med andra ord, du behöver skapa/ha en instans inom räckvidden för din statiska metod för att kunna få åtkomst till dess instansmetod.

Jag är inte säker på om instans-/statisk-konceptet som förklaras här tillämpas helt på detta sätt i TypeScript, men att anropa en instans från en separat statisk metod verkar inte vara en bra idé med tanke på den allmänna förståelsen av statisk.

Relaterade artiklar