aXises
aXises

Reputation: 21

Typescript: How to get subclass instance using parent get method

Suppose I have a parent class with a static method that returns an instance,

abstract class AbstractManager {
    private static instance: AbstractManager;

    constructor() {
        AbstractManager.instance = this;
    }

    public static getInstance(): AbstractManager {
        return this.instance
    }

}

And I have a child class which extends the parent class,

class Manager extends AbstractManager {
    constructor() {
        super();
    }
}

If I invoke Manager.getInstance() the return type is of the parent AbstractManager.

Is there a way to set up the parent getInstance() method so that it returns the child type instead?

Obviously, I can add a getInstance() to each of the children class returning or casting to the child type but should I have 100 subclasses then I'll need to write the method 100 times.

Although my knowledge of generics is limited, another solution I have attempted using generics is,

public static getInstance<T extends AbstractManager>(): T {
    return this.instance;
}

But this has caused the error Type 'AbstractManager' is not assignable to type 'T'.

Is it possible to set it up such that

Manager.getInstance() // is of type Manager not AbstractManager.

Or should I approach this problem in a different way? Thank you.

Upvotes: 2

Views: 2216

Answers (1)

distante
distante

Reputation: 7005

Your getInstance method is a static method of AbstractManager class, it does not do anything with instantiated classes. remove the static.

Also you do not need the instance member.

abstract class AbstractManager {

    constructor() {
    }

    public getInstance(): this {
        return this
    }

}

class Manager extends AbstractManager {
    managerTalk() {
        console.log("Hello I am Manager");
    }
    constructor() {
        super();
    }
}

const manager = new Manager();

const instance = manager.getInstance();
console.log(manager.getInstance()) // <--Manager

manager.managerTalk();
instance.managerTalk();

Take a look in Typescript Playground

enter image description here

Upvotes: 1

Related Questions