Merott
Merott

Reputation: 7379

TypeScript: self-referencing return type for methods in inheriting classes

Disclaimer: I'm finding it hard to summarise the problem in the title of the question, so if you have better suggestions, please let me know in the comments.

Let's take the following simplified TypeScript class:

class Model {
  save():Model {
    // save the current instance and return it
  }
}

The Model class has a save() method that returns an instance of itself: a Model.

We can extend Model like so:

class SomeModel extends Model {
  // inherits the save() method
}

So, SomeModel will inherit save(), but it still returns a Model, not a SomeModel.

Is there a way, perhaps using generics, to set the return type of save() in SomeModel to SomeModel, without having to redefine it inside of the inheriting class?

Upvotes: 3

Views: 4987

Answers (2)

Val
Val

Reputation: 22797

I know I'm late to the party,
@2019 I found a way to make return type specific:

class Model {
  save<T extends Model>(this: T): T {
    // save the current instance and return it
  }
}

This way whatever extends Model, or Model itself, will be referenced as return type when called.

And with Typescript@3, this also works:

class Model {
  save(): this {
    // save the current instance and return it
  }
}

Upvotes: 7

David Sherret
David Sherret

Reputation: 106770

You're in luck. Polymorphic this just came out in TypeScript 1.7. Upgrade to TypeScript 1.7 and then remove the explicit return type and it will work perfectly:

class Model {
    save() {
        return this;
    }
}

class SomeModel extends Model {
    otherMethod() {
    }
}

let someModel = new SomeModel().save();
// no compile error since someModel is typed as SomeModel in TS 1.7+
someModel.otherMethod();

Upvotes: 3

Related Questions