2

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.

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

6 Comments

Hi, thanks for the reply, the point of the static method is so I can retrieve the same instance of the class. In your solution, the manager.getInstance() method still has a return type of AbstractManager, not the child type Manager in visual studio code.
@aXises no it is not. Take a look at the link in my updated answer.
add any instance method to the child class and the typescript playground will also display an error stating that the property does not exist on type AbstractManager. I have taken a screenshot since the playground link does not fit here. Image
@aXises that was my fault, I forgot to remove the AbstractManager from the return type of getInstance to Typescript got the type wrong (but it was just a compilation issue). Answer updated.
Great, setting the return type to this will also work. Is it possible to set it up a way such that it can be invoked from a static context? This way the same instance can be used and retrieved by using the static getInstance() method.
|

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.