TypeScript: self-referencing return type for metho

2019-07-14 02:30发布

问题:

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?

回答1:

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();


回答2:

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

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
  }
}