Home > Software design >  How to correctly type the return value of factory method
How to correctly type the return value of factory method

Time:07-08

I have a base class which looks like this

class Base {
    protected constructor() {}

    static create() {
         return new this;
    }
}

Now, when I extend this class and try to initialise I get a typescript error

class Bar extends Base {
    magic() {}
}

let bar: Bar;
bar = Bar.create(); // <-- Typescript error

The error is

  Property 'magic' is missing in type 'Base' but required in type 'Bar'

So it seems that typescript expects that the returned value of create is an instance of Base, but is in fact Bar.

I can fix this as follows

class Base {
    protected constructor() {}

    static create<T>(): T {
         return new this as T;
    }
}

and

bar = Bar.create<Bar>();

I would expect that all this is not necessary, because it is pretty clear what the return type is. But how can I tell typescript what the return type is?

CodePudding user response:

You problem is that you do not override create in the subclass.

static create() {
    return new this;
}

This method has an implicit return type of Base.

In an non-static method, you could return this, but it's not possible here.

The Polymorphic this for static methods is a long known issue

  • Related