Alf Sanzo
Alf Sanzo

Reputation: 141

Calling static method from non-static method in Typescript

I have some static stuff in all my hierarchy (in this example, the _image). I would want to be able to access the correspondant _image without having to repeat the code:

This would be great:

class Actor {
    static _image; // I need it to be static

    method show(){  // I need it to be non-static
        this.setImage(this.class._image); //doesn't work....
    }
}

class GoodActor extends Actor {
    static _image = 'good.png'
}

class BadActor extends Actor {
    static _image = 'bad.png'
}

class MediumActor extends Actor {
    static _image = 'medium.png'
}

But it doesn't work. Right now I only got to:

class Actor {
}

class GoodActor extends Actor {
    static _image = 'good.png'  // I need it to be static

    method show(){   // I need it to be non-static
        this.setImage(GoodActor._image);
    }
}

class BadActor extends Actor {
    static _image = 'bad.png'  // I need it to be static

    method show(){  // I need it to be non-static
        this.setImage(BadActor._image);
    }
}

class MediumActor extends Actor {
    static _image = 'medium.png'  // I need it to be static

    method show(){  // I need it to be non-static
        this.setImage(MediumActor._image);
    }
}

Suppose those four classes have more methods. I don't want to have to repeat the show() method in every subclass... Yet I need the show() method to be non static and the _image to be statically accessed.

I have read this issue https://github.com/Microsoft/TypeScript/issues/7673 but unfortunatelly I can't ask there as they have closed it without fixing it. None of them talked about this problem of needing to dynamically resolve the static method to be invoked.

Upvotes: 1

Views: 3629

Answers (2)

fjc
fjc

Reputation: 5815

Update: Why don't you want to construct the individual objects prior to caching images? If you make construction inexpensive, there's no benefit of using static fields.

Example:

class Actor {
    image: string;

    showImage() {
        console.log(this.image);
    }
}


class GoodActor extends Actor {
    image = 'good.png';
}

class BadActor extends Actor {
    image = 'bad.png';
}

const myActorTypes: (typeof Actor)[] = [GoodActor, BadActor];

function preloadImages() {
    for (let myActorType of myActorTypes) {
        preloadImage(new myActorType().image);
    }
}

function preloadImage(image: string) {
    console.log(`Loading ${image}`);
}

preloadImages();

// "Loading good.png"
// "Loading bad.png"

Upvotes: 3

Matt McCutchen
Matt McCutchen

Reputation: 30879

FTR, you can access the class of the current object. It's called constructor, not class, and you'll need to declare it so that it has a more useful type than Function.

class Actor {
    static _image: string; // I need it to be static

    // Keep static members, remove construct signature because
    // subclasses may define constructors with different parameters. 
    "constructor": Pick<typeof Actor, keyof typeof Actor>;

    show(){  // I need it to be non-static
        this.setImage(this.constructor._image);
    }
}

class GoodActor extends Actor {
    static _image = 'good.png'
}

class BadActor extends Actor {
    static _image = 'bad.png'
}

class MediumActor extends Actor {
    static _image = 'medium.png'
}

Upvotes: 3

Related Questions