7

Is there a way in TypeScript to create new instances from a static method in a generic way?

I want to do something like:

class Base {
    static getInstance() {
         return new self(); // i need this line :)
    }
}

class Test extends Base {
}

class NextTest extends Base {
}

var test = Test.getInstance();
assert(test instanceof Test).toBe(true);

var nextTest = NextTest.getInstance();
assert(nextTest instanceof NextTest).toBe(true);

It would be really helpful if someone did something like this before and could help me. Maybe there is a JavaScript way?

Thanks in advance.

2
  • I'm curious... why would this be useful? Commented Apr 16, 2015 at 20:34
  • I am going to build TypeScript Models with an integrated RESTful Client. So you can import TestModel and call TestModel.objects.all() which needs to return a TestModel :D Somehow the objects class (actually it is the REST client) needs to know which Model to populate. Commented Apr 16, 2015 at 22:16

2 Answers 2

17

Hack :)

static getInstance() {
     return new this;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for this.. I always tried my approach with a static property not with a method :D Similar to: "static prop: Manager = new Manager(new this);" - Which is not compiling :) I will go with a static method
When I try this I get the following error: error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
How one calls super? Doesn't work because I get the wrong type.
-4

You can also use class name itself which in your example is Base,

static getInstance() {
   return new Base()
}

Another example is below which uses Greeter class name inside static function called createInstance, you can test following example at TypeScript Playground

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }

    static createInstance(message: any) {
        return new Greeter(message);
    }
}

let greeter = Greeter.createInstance("world");

let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() {
    alert(greeter.greet());
}

document.body.appendChild(button);

Hope it helps.

2 Comments

This was answered correctly 2 years ago. Your answer does not return subclasses as per the question.
Thanks for the update @mrm . Didn't notice about the sub classes requirement above. I was just trying out different codes and found an example with the Base class instead of 'this', just wanted to elaborate about using classname instead of this which also works if sub classing requirement isn't there, though haven't tested it out but I'll believe what you are saying as you already have tested it out. Thanks for pointing it out, helps the other users.

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.