1

I have a class, let's call it CoolClass which I am using all over my code to access it's static properties. However, I have a setup step within CoolClass that I define as a function as part of my class; let's call it doSetupStuff(). To get that to fire I call it via setting a static dummy variable.

This is my current solution which is working:

export default class CoolClass {
    public static readonly something = 'cool';
    public static readonly somethingelse = 12345;

    // GOAL: how can we call doSomeStuff() only once, without setting this 'dummy' variable?
    public static readonly dummy = CoolClass.doSetupStuff();

    public static doSetupStuff(): void {
        console.log('doing setup...');
        // more logic here...
    }
}

But this feels incorrect to me because I never actually need CoolClass.dummy - I just need to run what is in doSetupStuff().

I know I can do this:

export default class CoolClass {
    public static readonly something = 'cool';
    public static readonly somethingelse = 12345;

    constructor() {
        this.doSetupStuff();
    }

    public doSetupStuff(): void {
        console.log('doing setup...');
        // more logic here...
    }
}

but then I can't use CoolClass statically. (i.e. I have to call new every time I want to use it in other parts of my code).

Surely there is no need to set a dummy variable like in my current solution. Does anyone have an idea? I can post the full code if needed, though I believe it is irrelevant to the pattern I wish to achieve.

2
  • Just export default class A {...} A.setup(); Commented May 8, 2020 at 15:34
  • 1
    I wonder about everything being static. Are you sure a singleton wouldn't be more appropriate? Commented May 8, 2020 at 15:36

1 Answer 1

3

I think I'd probably declare it, set it up, and then export it

class CoolClass {
    public static readonly something = 'cool';
    public static readonly somethingelse = 12345;

    public static doSetupStuff(): void {
        console.log('yay!');
    }
}
CoolClass.doSetupStuff();
export default CoolClass;

That said, having doSetupStuff be public is probably less than ideal unless it's meant to be called by users of the class. You could hide that function if it only works with public aspects of the class:

class CoolClass {
    public static readonly something = 'cool';
    public static readonly somethingelse = 12345;
}
function doSetupStuff(): void {
    console.log('yay!');
}
doSetupStuff();
export default CoolClass;

That said, I'd be tempted by a singleton instead:

class CoolClass {
    public readonly something = 'cool';
    public readonly somethingelse = 12345;

    constructor() {
        console.log('yay!'); // Setup here...
    }
}
export default new CoolClass();
Sign up to request clarification or add additional context in comments.

4 Comments

That's right, but you don't need to split the definition and the export. The module will be evaluated before you can import the class anyway. Might be clearer as you have it though
@AluanHaddad - Yeah, it was mostly for clarity.
@T.J.Crowder - great, thanks for the detailed response! In the end, I went with your second example. The export default new CoolClass() pattern wasn't working for me (also, wouldn't that mean a new instance would be created any time I import it anywhere else?). Example 2 is nice for me because indeed as you said, this 'setup' step should not be exposed publicly - nor does it need to be.
@fullStackChris - "The export default new CoolClass() pattern wasn't working for me" Do you know why not? "(also, wouldn't that mean a new instance would be created any time I import it anywhere else?)" No, just once when your module is evaluated. All imports would import the same instance of CoolClass.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.